"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SourceMapper = void 0;
const sourcemap_codec_1 = require("@jridgewell/sourcemap-codec");
function binaryInsert(array, value, key) {
    if (0 === key) {
        key = '0';
    }
    const index = 1 + binarySearch(array, (key ? value[key] : value), key);
    let i = array.length;
    while (index !== i--) {
        array[1 + i] = array[i];
    }
    array[index] = value;
}
function binarySearch(array, target, key) {
    if (!array || 0 === array.length) {
        return -1;
    }
    if (0 === key) {
        key = '0';
    }
    let low = 0;
    let high = array.length - 1;
    while (low <= high) {
        const i = low + ((high - low) >> 1);
        const item = (undefined === key ? array[i] : array[i][key]);
        if (item === target) {
            return i;
        }
        if (item < target) {
            low = i + 1;
        }
        else {
            high = i - 1;
        }
    }
    if ((low = ~low) < 0) {
        low = ~low - 1;
    }
    return low;
}
class SourceMapper {
    constructor(mappings) {
        if (typeof mappings === 'string') {
            this.mappings = (0, sourcemap_codec_1.decode)(mappings);
        }
        else {
            this.mappings = mappings;
        }
    }
    getOriginalPosition(position) {
        const lineMap = this.mappings[position.line];
        if (!lineMap) {
            return { line: -1, character: -1 };
        }
        const closestMatch = binarySearch(lineMap, position.character, 0);
        const match = lineMap[closestMatch];
        if (!match) {
            return { line: -1, character: -1 };
        }
        const { 2: line, 3: character } = match;
        return { line, character };
    }
    getGeneratedPosition(position) {
        if (!this.reverseMappings) {
            this.computeReversed();
        }
        const lineMap = this.reverseMappings[position.line];
        if (!lineMap) {
            return { line: -1, character: -1 };
        }
        const closestMatch = binarySearch(lineMap, position.character, 0);
        const match = lineMap[closestMatch];
        if (!match) {
            return { line: -1, character: -1 };
        }
        const { 1: line, 2: character } = match;
        return { line, character };
    }
    computeReversed() {
        this.reverseMappings = {};
        for (let generated_line = 0; generated_line !== this.mappings.length; generated_line++) {
            for (const { 0: generated_index, 2: original_line, 3: original_character_index } of this
                .mappings[generated_line]) {
                const reordered_char = [
                    original_character_index,
                    generated_line,
                    generated_index
                ];
                if (original_line in this.reverseMappings) {
                    binaryInsert(this.reverseMappings[original_line], reordered_char, 0);
                }
                else {
                    this.reverseMappings[original_line] = [reordered_char];
                }
            }
        }
    }
}
exports.SourceMapper = SourceMapper;
//# sourceMappingURL=source-mapper.js.map