/* --------------------------------------------------------------------------------------------
 * Copyright (c) Remy Suen. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 * ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.DockerSemanticTokens = exports.TokensLegend = void 0;
var vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
var vscode_languageserver_types_1 = require("vscode-languageserver-types");
var dockerfile_ast_1 = require("dockerfile-ast");
var docker_1 = require("./docker");
var TokensLegend = /** @class */ (function () {
    function TokensLegend() {
    }
    TokensLegend.init = function () {
        var counter = 0;
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.keyword] = counter++; // 0
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.comment] = counter++; // 1
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.parameter] = counter++; // 2
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.property] = counter++; // 3
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.namespace] = counter++; // 4
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.class] = counter++; // 5
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.macro] = counter++; // 6
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.string] = counter++; // 7
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.variable] = counter++; // 8
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.operator] = counter++; // 9
        this.tokenTypes[vscode_languageserver_types_1.SemanticTokenTypes.modifier] = counter++; // 10
        this.tokenModifiers[vscode_languageserver_types_1.SemanticTokenModifiers.declaration] = 1;
        this.tokenModifiers[vscode_languageserver_types_1.SemanticTokenModifiers.definition] = 2;
        this.tokenModifiers[vscode_languageserver_types_1.SemanticTokenModifiers.deprecated] = 4;
    };
    TokensLegend.getTokenType = function (type) {
        var tokenType = this.tokenTypes[type];
        return tokenType;
    };
    TokensLegend.getTokenModifiers = function (modifiers) {
        var bit = 0;
        for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) {
            var modifier = modifiers_1[_i];
            bit |= this.tokenModifiers[modifier];
        }
        return bit;
    };
    TokensLegend.tokenTypes = {};
    TokensLegend.tokenModifiers = {};
    return TokensLegend;
}());
exports.TokensLegend = TokensLegend;
TokensLegend.init();
var DockerSemanticTokens = /** @class */ (function () {
    function DockerSemanticTokens(content) {
        this.currentRange = null;
        this.tokens = [];
        this.quote = null;
        this.escapedQuote = null;
        this.content = content;
        this.document = vscode_languageserver_textdocument_1.TextDocument.create("", "", 0, content);
        this.dockerfile = dockerfile_ast_1.DockerfileParser.parse(content);
        this.escapeCharacter = this.dockerfile.getEscapeCharacter();
    }
    DockerSemanticTokens.prototype.computeSemanticTokens = function () {
        var lines = this.dockerfile.getComments();
        var instructions = this.dockerfile.getInstructions();
        for (var _i = 0, instructions_1 = instructions; _i < instructions_1.length; _i++) {
            var instruction = instructions_1[_i];
            var range = instruction.getRange();
            if (range.start.line !== range.end.line) {
                for (var i = 0; i < lines.length; i++) {
                    var commentRange = lines[i].getRange();
                    if (range.start.line < commentRange.start.line && commentRange.start.line < range.end.line) {
                        // this is an embedded comment, remove it
                        lines.splice(i, 1);
                        i--;
                    }
                }
            }
        }
        lines = lines.concat(this.dockerfile.getInstructions());
        lines.sort(function (a, b) {
            return a.getRange().start.line - b.getRange().start.line;
        });
        for (var _a = 0, _b = this.dockerfile.getDirectives(); _a < _b.length; _a++) {
            var directive = _b[_a];
            var range = directive.getRange();
            var nameRange = directive.getNameRange();
            var prefixRange = { start: range.start, end: nameRange.start };
            this.createToken(null, prefixRange, vscode_languageserver_types_1.SemanticTokenTypes.comment, [], false);
            this.createToken(null, nameRange, vscode_languageserver_types_1.SemanticTokenTypes.property, [], false);
            var valueRange = directive.getValueRange();
            var operatorRange = {
                start: { character: valueRange.start.character - 1, line: valueRange.start.line },
                end: { character: valueRange.start.character, line: valueRange.start.line },
            };
            this.createToken(null, operatorRange, vscode_languageserver_types_1.SemanticTokenTypes.operator, [], false);
            if (valueRange.start.character !== valueRange.end.character) {
                this.createToken(null, valueRange, vscode_languageserver_types_1.SemanticTokenTypes.parameter, [], false);
            }
        }
        for (var i = 0; i < lines.length; i++) {
            if (lines[i] instanceof dockerfile_ast_1.Comment) {
                var range = lines[i].getRange();
                this.createToken(null, range, vscode_languageserver_types_1.SemanticTokenTypes.comment, [], false);
            }
            else {
                // trailing open quotes should not cause subsequent argument parameters to be flagged as strings
                this.quote = null;
                this.escapedQuote = null;
                this.createTokensForInstruction(lines[i]);
            }
        }
        return {
            data: this.tokens
        };
    };
    DockerSemanticTokens.prototype.createTokensForInstruction = function (instruction) {
        var instructionRange = instruction.getInstructionRange();
        var modifiers = [];
        if (instruction.getKeyword() === dockerfile_ast_1.Keyword.MAINTAINER) {
            modifiers = [vscode_languageserver_types_1.SemanticTokenModifiers.deprecated];
        }
        this.createToken(instruction, instructionRange, vscode_languageserver_types_1.SemanticTokenTypes.keyword, modifiers);
        if (instruction instanceof dockerfile_ast_1.ModifiableInstruction) {
            for (var _i = 0, _a = instruction.getFlags(); _i < _a.length; _i++) {
                var flag = _a[_i];
                var flagRange = flag.getRange();
                var nameRange = flag.getNameRange();
                var mergedRange = {
                    start: flagRange.start,
                    end: nameRange.end
                };
                this.createToken(instruction, mergedRange, vscode_languageserver_types_1.SemanticTokenTypes.parameter);
                var flagValue = flag.getValue();
                if (flagValue !== null) {
                    if (flag.hasOptions()) {
                        var operatorRange = {
                            start: mergedRange.end,
                            end: {
                                line: mergedRange.end.line,
                                character: mergedRange.end.character + 1
                            }
                        };
                        this.createToken(instruction, operatorRange, vscode_languageserver_types_1.SemanticTokenTypes.operator, [], false, false);
                        for (var _b = 0, _c = flag.getOptions(); _b < _c.length; _b++) {
                            var option = _c[_b];
                            nameRange = option.getNameRange();
                            this.createToken(instruction, nameRange, vscode_languageserver_types_1.SemanticTokenTypes.parameter);
                            var valueRange = option.getValueRange();
                            if (valueRange !== null) {
                                var operatorRange_1 = {
                                    start: nameRange.end,
                                    end: valueRange.start
                                };
                                this.createToken(instruction, operatorRange_1, vscode_languageserver_types_1.SemanticTokenTypes.operator, [], false, false);
                                if (option.getValue() !== "") {
                                    this.createToken(instruction, valueRange, vscode_languageserver_types_1.SemanticTokenTypes.property);
                                }
                            }
                        }
                    }
                    else {
                        var valueRange = flag.getValueRange();
                        var operatorRange = {
                            start: mergedRange.end,
                            end: valueRange.start
                        };
                        this.createToken(instruction, operatorRange, vscode_languageserver_types_1.SemanticTokenTypes.operator, [], false, false);
                        if (flagValue !== "") {
                            this.createToken(instruction, valueRange, vscode_languageserver_types_1.SemanticTokenTypes.property);
                        }
                    }
                }
            }
        }
        var args = instruction.getArguments();
        if (args.length === 0) {
            var range = instruction.getRange();
            if (range.start.line !== range.end.line) {
                // multiline instruction with no arguments,
                // only escaped newlines and possibly comments
                this.handleLineChange(instruction, instructionRange.end, range.end);
            }
            return;
        }
        switch (instruction.getKeyword()) {
            case dockerfile_ast_1.Keyword.ARG:
            case dockerfile_ast_1.Keyword.ENV:
                var propertyInstruction = instruction;
                for (var _d = 0, _e = propertyInstruction.getProperties(); _d < _e.length; _d++) {
                    var property = _e[_d];
                    var nameRange = property.getNameRange();
                    this.createToken(instruction, nameRange, vscode_languageserver_types_1.SemanticTokenTypes.variable, [vscode_languageserver_types_1.SemanticTokenModifiers.declaration], false);
                    var valueRange = property.getValueRange();
                    if (valueRange !== null) {
                        var operatorRange = {
                            start: nameRange.end,
                            end: valueRange.start
                        };
                        if (this.document.getText(operatorRange).startsWith("=")) {
                            var nameRangeEnd = this.document.offsetAt(nameRange.end);
                            operatorRange = { start: nameRange.end, end: this.document.positionAt(nameRangeEnd + 1) };
                            this.createToken(instruction, operatorRange, vscode_languageserver_types_1.SemanticTokenTypes.operator, [], false, false);
                        }
                        this.createToken(instruction, valueRange, vscode_languageserver_types_1.SemanticTokenTypes.parameter, [], true, true);
                    }
                }
                return;
            case dockerfile_ast_1.Keyword.FROM:
                var from = instruction;
                this.createToken(instruction, from.getImageNameRange(), vscode_languageserver_types_1.SemanticTokenTypes.class);
                var tagRange = from.getImageTagRange();
                if (tagRange !== null) {
                    this.createToken(instruction, tagRange, vscode_languageserver_types_1.SemanticTokenTypes.property);
                }
                var digestRange = from.getImageDigestRange();
                if (digestRange !== null) {
                    this.createToken(instruction, digestRange, vscode_languageserver_types_1.SemanticTokenTypes.property);
                }
                var fromArgs = instruction.getArguments();
                if (fromArgs.length > 1) {
                    if (fromArgs[1].getValue().toUpperCase() === "AS") {
                        var range_1 = fromArgs[1].getRange();
                        this.createToken(instruction, range_1, vscode_languageserver_types_1.SemanticTokenTypes.keyword);
                        if (fromArgs.length > 2) {
                            this.createToken(instruction, fromArgs[2].getRange(), vscode_languageserver_types_1.SemanticTokenTypes.namespace);
                            if (fromArgs.length > 3) {
                                this.createArgumentTokens(instruction, fromArgs.slice(3));
                            }
                        }
                    }
                    else {
                        this.createArgumentTokens(instruction, fromArgs.slice(1));
                    }
                }
                return;
            case dockerfile_ast_1.Keyword.HEALTHCHECK:
                var healthcheck = instruction;
                var range = healthcheck.getSubcommand().getRange();
                this.createToken(instruction, range, vscode_languageserver_types_1.SemanticTokenTypes.keyword);
                if (args.length > 1) {
                    this.createArgumentTokens(instruction, args.slice(1));
                }
                return;
            case dockerfile_ast_1.Keyword.ONBUILD:
                var onbuild = instruction;
                this.createTokensForInstruction(onbuild.getTriggerInstruction());
                return;
        }
        this.createArgumentTokens(instruction, args);
    };
    DockerSemanticTokens.prototype.createArgumentTokens = function (instruction, args) {
        var lastRange = null;
        for (var i = 0; i < args.length; i++) {
            lastRange = args[i].getRange();
            this.createToken(instruction, args[i].getRange(), vscode_languageserver_types_1.SemanticTokenTypes.parameter, [], true, true);
        }
        var instructionRange = instruction.getRange();
        if (lastRange.end.line !== instructionRange.end.line || lastRange.end.character !== instructionRange.end.character) {
            this.handleLineChange(instruction, lastRange.end, instructionRange.end);
        }
    };
    DockerSemanticTokens.prototype.handleLineChange = function (instruction, checkStart, checkEnd) {
        var comment = -1;
        for (var i = this.document.offsetAt(checkStart); i < this.document.offsetAt(checkEnd); i++) {
            switch (this.content.charAt(i)) {
                case this.escapeCharacter:
                    // mark the escape character if it's not in a comment 
                    if (comment === -1) {
                        this.createEscapeToken(instruction, i);
                    }
                    break;
                case '\r':
                case '\n':
                    if (comment !== -1) {
                        var commentRange = {
                            start: this.document.positionAt(comment),
                            end: this.document.positionAt(i)
                        };
                        this.createToken(null, commentRange, vscode_languageserver_types_1.SemanticTokenTypes.comment, [], false);
                        comment = -1;
                    }
                    break;
                case '#':
                    if (comment === -1) {
                        comment = i;
                    }
                    break;
            }
        }
    };
    DockerSemanticTokens.prototype.createEscapeToken = function (instruction, offset) {
        var escapeRange = {
            start: this.document.positionAt(offset),
            end: this.document.positionAt(offset + 1),
        };
        this.createToken(instruction, escapeRange, vscode_languageserver_types_1.SemanticTokenTypes.macro, [], false, false, false);
    };
    DockerSemanticTokens.prototype.createVariableToken = function (instruction, variable, range) {
        var modifierRange = variable.getModifierRange();
        if (modifierRange === null) {
            this.createToken(instruction, range, vscode_languageserver_types_1.SemanticTokenTypes.variable, [], false);
        }
        else {
            var operatorRange = vscode_languageserver_types_1.Range.create(vscode_languageserver_types_1.Position.create(modifierRange.start.line, modifierRange.start.character - 1), modifierRange.start);
            if (range.start.character < operatorRange.start.character) {
                // the operator is in the range, handle the content before the operator and the operator
                this.createToken(instruction, vscode_languageserver_types_1.Range.create(range.start, operatorRange.start), vscode_languageserver_types_1.SemanticTokenTypes.variable, [], false);
                this.createToken(instruction, operatorRange, vscode_languageserver_types_1.SemanticTokenTypes.operator, [], false, false, false);
            }
            // check if there is more content after the operator to process
            if (range.end.character > operatorRange.end.character) {
                if (modifierRange.end.character >= range.start.character) {
                    // only render the modifier if there is one, the variable may be ${var:} which we then want to skip
                    if (modifierRange.start.character !== modifierRange.end.character) {
                        this.createToken(instruction, modifierRange, vscode_languageserver_types_1.SemanticTokenTypes.modifier, [], false, false, false);
                    }
                    // process the content between the modifier and the end of the range if applicable
                    if (modifierRange.end.character !== range.end.character) {
                        this.createToken(instruction, vscode_languageserver_types_1.Range.create(modifierRange.end, range.end), vscode_languageserver_types_1.SemanticTokenTypes.variable, [], false);
                    }
                }
                else {
                    this.createToken(instruction, range, vscode_languageserver_types_1.SemanticTokenTypes.variable, [], false);
                }
            }
        }
    };
    DockerSemanticTokens.prototype.createToken = function (instruction, range, tokenType, tokenModifiers, checkVariables, checkStrings, checkNewline) {
        if (tokenModifiers === void 0) { tokenModifiers = []; }
        if (checkVariables === void 0) { checkVariables = true; }
        if (checkStrings === void 0) { checkStrings = false; }
        if (checkNewline === void 0) { checkNewline = true; }
        if (checkNewline && this.currentRange !== null && this.currentRange.end.line !== range.start.line) {
            // this implies that there's been a line change between one arg and the next
            this.handleLineChange(instruction, this.currentRange.end, range.start);
        }
        if (checkStrings) {
            var startOffset = this.document.offsetAt(range.start);
            var quoteStart = startOffset;
            var newOffset = -1;
            var escaping = false;
            var endOffset = this.document.offsetAt(range.end);
            stringsCheck: for (var i = startOffset; i < endOffset; i++) {
                var ch = this.content.charAt(i);
                switch (ch) {
                    case this.escapeCharacter:
                        escapeCheck: for (var j = i + 1; j < endOffset; j++) {
                            var escapedCh = this.content.charAt(j);
                            switch (escapedCh) {
                                case ' ':
                                case '\t':
                                    continue;
                                case '\r':
                                    j++;
                                case '\n':
                                    escaping = true;
                                    i = j;
                                    continue stringsCheck;
                                default:
                                    break escapeCheck;
                            }
                        }
                        escaping = false;
                        if (startOffset === -1) {
                            startOffset = i;
                        }
                        break;
                    case '\'':
                    case '"':
                        escaping = false;
                        if (this.quote === null) {
                            if (this.escapedQuote === null) {
                                this.quote = ch;
                                quoteStart = i;
                                if (startOffset !== -1 && startOffset !== quoteStart) {
                                    var intermediateRange = {
                                        start: this.document.positionAt(startOffset),
                                        end: this.document.positionAt(quoteStart),
                                    };
                                    this.createToken(instruction, intermediateRange, tokenType, tokenModifiers);
                                }
                            }
                        }
                        else if (this.quote === ch) {
                            var quoteRange = {
                                start: this.document.positionAt(quoteStart),
                                end: this.document.positionAt(i + 1),
                            };
                            this.createToken(instruction, quoteRange, vscode_languageserver_types_1.SemanticTokenTypes.string, [], true, false);
                            newOffset = i + 1;
                            startOffset = -1;
                            this.quote = null;
                        }
                        break;
                    case '#':
                        if (escaping) {
                            for (var j = i + 1; j < endOffset; j++) {
                                var escapedCh = this.content.charAt(j);
                                switch (escapedCh) {
                                    case '\r':
                                        j++;
                                    case '\n':
                                        i = j;
                                        continue stringsCheck;
                                }
                            }
                            break;
                        }
                    case ' ':
                    case '\t':
                    case '\r':
                    case '\n':
                        if (escaping) {
                            continue;
                        }
                    default:
                        escaping = false;
                        if (startOffset === -1) {
                            startOffset = i;
                        }
                        break;
                }
            }
            if (this.quote !== null) {
                var quoteRange = {
                    start: this.document.positionAt(quoteStart),
                    end: this.document.positionAt(endOffset),
                };
                this.createToken(instruction, quoteRange, vscode_languageserver_types_1.SemanticTokenTypes.string, [], true, false);
                return;
            }
            else if (newOffset !== -1) {
                if (newOffset !== endOffset) {
                    var intermediateRange = {
                        start: this.document.positionAt(newOffset),
                        end: this.document.positionAt(endOffset),
                    };
                    this.createToken(instruction, intermediateRange, tokenType, tokenModifiers);
                }
                return;
            }
            else if (this.quote !== null || this.escapedQuote !== null) {
                // there is now an open string, change the token to a string
                tokenType = vscode_languageserver_types_1.SemanticTokenTypes.string;
                // reset the range to the start of the string
                range = {
                    start: this.document.positionAt(quoteStart),
                    end: range.end
                };
            }
        }
        if (range.start.line !== range.end.line) {
            var startOffset = this.document.offsetAt(range.start);
            var endOffset = this.document.offsetAt(range.end);
            var intermediateAdded = false;
            var handleNewlines = true;
            var escaping = false;
            for (var i = startOffset; i < endOffset; i++) {
                var ch = this.content.charAt(i);
                switch (ch) {
                    case '#':
                        if (escaping) {
                            var commenting = true;
                            commentCheck: for (var j = i + 1; j < endOffset; j++) {
                                switch (this.content.charAt(j)) {
                                    case ' ':
                                    case '\t':
                                        break;
                                    case '\r':
                                        var crComment = {
                                            start: this.document.positionAt(i),
                                            end: this.document.positionAt(j)
                                        };
                                        this.createToken(null, crComment, vscode_languageserver_types_1.SemanticTokenTypes.comment, [], false);
                                        i = j + 1;
                                        startOffset = -1;
                                        commenting = false;
                                        j++;
                                        break;
                                    case '\n':
                                        var lfComment = {
                                            start: this.document.positionAt(i),
                                            end: this.document.positionAt(j)
                                        };
                                        this.createToken(null, lfComment, vscode_languageserver_types_1.SemanticTokenTypes.comment, [], false);
                                        i = j;
                                        startOffset = -1;
                                        commenting = false;
                                        break;
                                    case '#':
                                        if (!commenting) {
                                            i = j;
                                        }
                                        commenting = true;
                                        break;
                                    default:
                                        if (commenting) {
                                            break;
                                        }
                                        i = j - 1;
                                        break commentCheck;
                                }
                            }
                        }
                        break;
                    case this.escapeCharacter:
                        // note whether the intermediate token has been added or not
                        var added = false;
                        escapeCheck: for (var j = i + 1; j < endOffset; j++) {
                            switch (this.content.charAt(j)) {
                                case ' ':
                                case '\t':
                                case '\r':
                                    break;
                                case '\n':
                                    if (!added) {
                                        if (!intermediateAdded && startOffset !== -1) {
                                            if (i !== startOffset) {
                                                var intermediateRange_1 = {
                                                    start: this.document.positionAt(startOffset),
                                                    end: this.document.positionAt(i),
                                                };
                                                this.createToken(instruction, intermediateRange_1, tokenType, tokenModifiers);
                                            }
                                            intermediateAdded = true;
                                        }
                                        this.createEscapeToken(instruction, i);
                                    }
                                    // escaped newlines have are being handled here already
                                    handleNewlines = false;
                                    escaping = true;
                                    added = true;
                                    i = j;
                                    startOffset = -1;
                                    break;
                                case '#':
                                    if (escaping) {
                                        i = j - 1;
                                        break escapeCheck;
                                    }
                                case '\\':
                                    if (!escaping) {
                                        intermediateAdded = false;
                                        escaping = false;
                                        i = j;
                                        break escapeCheck;
                                    }
                                    i = j;
                                    added = false;
                                    startOffset = j;
                                    break;
                                default:
                                    if (startOffset === -1) {
                                        intermediateAdded = false;
                                        escaping = false;
                                        startOffset = j;
                                        i = j;
                                    }
                                    break escapeCheck;
                            }
                        }
                        break;
                    default:
                        if (startOffset === -1) {
                            intermediateAdded = false;
                            escaping = false;
                            startOffset = i;
                        }
                        break;
                }
            }
            if (startOffset === -1) {
                // we've processed the intermediate token but there is nothing of interest after it
                return;
            }
            var intermediateRange = {
                start: this.document.positionAt(startOffset),
                end: this.document.positionAt(endOffset),
            };
            this.createToken(instruction, intermediateRange, tokenType, tokenModifiers, checkVariables, checkStrings, handleNewlines);
            return;
        }
        if (checkVariables) {
            var startPosition = range.start;
            var lastVariableRange = null;
            for (var _i = 0, _a = instruction.getVariables(); _i < _a.length; _i++) {
                var variable = _a[_i];
                var variableRange = variable.getRange();
                if (docker_1.Util.isInsideRange(range.start, variableRange) && docker_1.Util.isInsideRange(range.end, variableRange)) {
                    if (tokenType === vscode_languageserver_types_1.SemanticTokenTypes.string) {
                        break;
                    }
                    // the token is completely inside the variable's range, render it as a variable
                    this.createVariableToken(instruction, variable, range);
                    return;
                }
                else if (docker_1.Util.isInsideRange(variableRange.start, range)) {
                    if (docker_1.Util.positionBefore(startPosition, variableRange.start)) {
                        // create a parameter token for the characters
                        // before the variable
                        this.createToken(instruction, {
                            start: startPosition,
                            end: variableRange.start
                        }, tokenType, tokenModifiers, false);
                    }
                    var variableProcessingRange = variableRange;
                    if (variableRange.end.character > range.end.character) {
                        variableProcessingRange.end = range.end;
                    }
                    this.createVariableToken(instruction, variable, variableProcessingRange);
                    lastVariableRange = variableRange;
                    if (docker_1.Util.positionEquals(range.end, variableRange.end)) {
                        return;
                    }
                    startPosition = variableRange.end;
                }
            }
            if (lastVariableRange !== null) {
                // alter the range so it is the characters that comes
                // after the last matched variable
                range = { start: lastVariableRange.end, end: range.end };
            }
        }
        if (this.currentRange === null) {
            this.tokens = this.tokens.concat([
                range.start.line,
                range.start.character,
                range.end.character - range.start.character,
                TokensLegend.getTokenType(tokenType),
                TokensLegend.getTokenModifiers(tokenModifiers)
            ]);
        }
        else if (this.currentRange.end.line !== range.start.line) {
            this.tokens = this.tokens.concat([
                range.start.line - this.currentRange.end.line,
                range.start.character,
                range.end.character - range.start.character,
                TokensLegend.getTokenType(tokenType),
                TokensLegend.getTokenModifiers(tokenModifiers)
            ]);
        }
        else {
            this.tokens = this.tokens.concat([
                range.start.line - this.currentRange.start.line,
                range.start.character - this.currentRange.start.character,
                range.end.character - range.start.character,
                TokensLegend.getTokenType(tokenType),
                TokensLegend.getTokenModifiers(tokenModifiers)
            ]);
        }
        this.currentRange = range;
    };
    return DockerSemanticTokens;
}());
exports.DockerSemanticTokens = DockerSemanticTokens;
