"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParseException = void 0;
const Autocompletion_js_1 = require("./core/Autocompletion.js");
const Lexer_js_1 = require("./core/Lexer.js");
const RDParser_js_1 = require("./core/RDParser.js");
class ParseException extends Error {
    constructor(root, failedTerminal, parser) {
        super();
        this.root = root;
        this.failedTerminal = failedTerminal;
        this.parser = parser;
        let tmp = failedTerminal;
        while (tmp != null && !tmp.doesAutocomplete())
            tmp = tmp.getParent();
        this.firstAutocompletingAncestorThatFailed = tmp;
        this.message = this.getError();
    }
    getRoot() {
        return this.root;
    }
    getFailedTerminal() {
        return this.failedTerminal;
    }
    getFirstAutocompletingAncestorThatFailed() {
        return this.firstAutocompletingAncestorThatFailed;
    }
    getError() {
        const lexer = this.parser.getLexer();
        const grammar = this.parser.getGrammar();
        const errorPos = this.failedTerminal.getMatcher().pos + this.failedTerminal.getMatcher().parsed.length - 1;
        // the character at last.matcher.pos failed, everything before must have been working
        const workingText = lexer.substring(0, this.failedTerminal.getMatcher().pos);
        // create a new parser and collect the autocompletions
        const workingLexer = new Lexer_js_1.Lexer(workingText);
        const parser2 = new RDParser_js_1.RDParser(grammar, workingLexer, this.parser.getParsedNodeFactory());
        const expectations = [];
        try {
            parser2.parse(expectations);
        }
        catch (e) {
            return "Error at position " + errorPos;
        }
        const lines = lexer.substring(0, errorPos + 1).split(/\r?\n|\r/);
        const errorLine = lines.length - 1;
        const errorPosInLastLine = lines[errorLine].length - 1;
        let errorMessage = "";
        const nl = "\n";
        errorMessage += "Error at position " + errorPos + " in line " + errorLine + ":" + nl;
        errorMessage += lines[errorLine] + nl;
        for (let i = 0; i < errorPosInLastLine; i++)
            errorMessage += " ";
        errorMessage += "^" + nl;
        const exString = expectations.map(ac => ac.getCompletion(Autocompletion_js_1.Autocompletion.Purpose.FOR_INSERTION));
        errorMessage += "Expected " + exString.toString();
        return errorMessage;
    }
}
exports.ParseException = ParseException;
//# sourceMappingURL=ParseException.js.map