text: "use strict";
  var __values = (this && this.__values) || function (o) {
      var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
      if (m) return m.call(o);
      return {
          next: function () {
              if (o && i >= o.length) o = void 0;
              return { value: o && o[i++], done: !o };
          }
      };
  };
  var __read = (this && this.__read) || function (o, n) {
      var m = typeof Symbol === "function" && o[Symbol.iterator];
      if (!m) return o;
      var i = m.call(o), r, ar = [], e;
      try {
          while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
      }
      catch (error) { e = { error: error }; }
      finally {
          try {
              if (r && !r.done && (m = i["return"])) m.call(i);
          }
          finally { if (e) throw e.error; }
      }
      return ar;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  var _ = require("lodash");
  var instructions_1 = require("./instructions");
  var RADIX = 10;
  /**
   * Receives a string with newlines and returns a map of byte offset to LineColumn
   * @param str A string to process
   */
  function getOffsetToLocation(str) {
      var e_1, _a;
      var offsetToLocation = { 0: { line: 1, column: 0 } };
      var currentOffset = 0;
      try {
          for (var _b = __values(str.split('')), _c = _b.next(); !_c.done; _c = _b.next()) {
              var char = _c.value;
              var location_1 = offsetToLocation[currentOffset];
              var isNewline = char === '\n';
              offsetToLocation[currentOffset + 1] = {
                  line: location_1.line + (isNewline ? 1 : 0),
                  column: isNewline ? 0 : location_1.column + 1,
              };
              currentOffset++;
          }
      }
      catch (e_1_1) { e_1 = { error: e_1_1 }; }
      finally {
          try {
              if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
          }
          finally { if (e_1) throw e_1.error; }
      }
      return offsetToLocation;
  }
  exports.getOffsetToLocation = getOffsetToLocation;
  /**
   * Parses a sourcemap string.
   * The solidity sourcemap format is documented here: https://github.com/ethereum/solidity/blob/develop/docs/miscellaneous.rst#source-mappings
   * @param indexToSourceCode index to source code
   * @param srcMap source map string
   * @param bytecodeHex contract bytecode
   * @param indexToSource index to source file path
   */
  function parseSourceMap(sourceCodes, srcMap, bytecodeHex, sources) {
      var e_2, _a;
      var bytecode = Uint8Array.from(Buffer.from(bytecodeHex, 'hex'));
      var pcToInstructionIndex = instructions_1.getPcToInstructionIndexMapping(bytecode);
      var fileIndexToOffsetToLocation = {};
      _.map(sourceCodes, function (sourceCode, fileIndex) {
          fileIndexToOffsetToLocation[fileIndex] = sourceCode === undefined ? {} : getOffsetToLocation(sourceCode);
      });
      var entries = srcMap.split(';');
      var lastParsedEntry = {};
      var instructionIndexToSourceRange = {};
      _.each(entries, function (entry, i) {
          // tslint:disable-next-line:no-unused-variable
          var _a = __read(entry.split(':'), 4), instructionIndexStrIfExists = _a[0], lengthStrIfExists = _a[1], fileIndexStrIfExists = _a[2], jumpTypeStrIfExists = _a[3];
          var instructionIndexIfExists = parseInt(instructionIndexStrIfExists, RADIX);
          var lengthIfExists = parseInt(lengthStrIfExists, RADIX);
          var fileIndexIfExists = parseInt(fileIndexStrIfExists, RADIX);
          var offset = _.isNaN(instructionIndexIfExists) ? lastParsedEntry.offset : instructionIndexIfExists;
          var length = _.isNaN(lengthIfExists) ? lastParsedEntry.length : lengthIfExists;
          var fileIndex = _.isNaN(fileIndexIfExists) ? lastParsedEntry.fileIndex : fileIndexIfExists;
          var parsedEntry = {
              offset: offset,
              length: length,
              fileIndex: fileIndex,
          };
          if (parsedEntry.fileIndex !== -1 && fileIndexToOffsetToLocation[parsedEntry.fileIndex] !== undefined) {
              var offsetToLocation = fileIndexToOffsetToLocation[parsedEntry.fileIndex];
              var sourceRange = {
                  location: {
                      start: offsetToLocation[parsedEntry.offset],
                      end: offsetToLocation[parsedEntry.offset + parsedEntry.length],
                  },
                  fileName: sources[parsedEntry.fileIndex],
              };
              if (sourceRange.location.start === undefined || sourceRange.location.end === undefined) {
                  console.error("Error while processing sourcemap: location out of range in " + sourceRange.fileName);
              }
              else {
                  instructionIndexToSourceRange[i] = sourceRange;
              }
          }
          else {
              // Some assembly code generated by Solidity can't be mapped back to a line of source code.
              // Source: https://github.com/ethereum/solidity/issues/3629
          }
          lastParsedEntry = parsedEntry;
      });
      var pcsToSourceRange = {};
      try {
          for (var _b = __values(_.keys(pcToInstructionIndex)), _c = _b.next(); !_c.done; _c = _b.next()) {
              var programCounterKey = _c.value;
              var pc = parseInt(programCounterKey, RADIX);
              var instructionIndex = pcToInstructionIndex[pc];
              pcsToSourceRange[pc] = instructionIndexToSourceRange[instructionIndex];
          }
      }
      catch (e_2_1) { e_2 = { error: e_2_1 }; }
      finally {
          try {
              if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
          }
          finally { if (e_2) throw e_2.error; }
      }
      return pcsToSourceRange;
  }
  exports.parseSourceMap = parseSourceMap;
  //# sourceMappingURL=source_maps.js.map