"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IfNothingYetEnteredAutocompleter = exports.EntireSequenceCompleter = exports.Autocompleter = void 0;
const Autocompletion_js_1 = require("./core/Autocompletion.js");
const BNF_js_1 = require("./core/BNF.js");
const Lexer_js_1 = require("./core/Lexer.js");
const Production_js_1 = require("./core/Production.js");
const RDParser_js_1 = require("./core/RDParser.js");
const EBNFParsedNodeFactory_js_1 = require("./ebnf/EBNFParsedNodeFactory.js");
const Sequence_js_1 = require("./ebnf/Sequence.js");
class IfNothingYetEnteredAutocompleter {
    constructor(ifNothingYetEntered, otherwise) {
        this.ifNothingYetEntered = ifNothingYetEntered;
        this.otherwise = otherwise;
    }
    getAutocompletion(pn, _justCheck) {
        if (pn.getParsedString().length === 0)
            return Autocompletion_js_1.Autocompletion.literal(pn, [this.ifNothingYetEntered]);
        if (this.otherwise !== undefined)
            return Autocompletion_js_1.Autocompletion.literal(pn, [this.otherwise]);
        return undefined;
    }
}
exports.IfNothingYetEnteredAutocompleter = IfNothingYetEnteredAutocompleter;
class EntireSequenceCompleter {
    constructor(ebnf, symbol2Autocompletion) {
        this.ebnf = ebnf;
        this.symbol2Autocompletion = symbol2Autocompletion;
    }
    getAutocompletion(pn, _justCheck) {
        const alreadyEntered = pn.getParsedString();
        const sequence = pn.getRule();
        const children = sequence.getChildren();
        const entireSequenceCompletion = new Autocompletion_js_1.Autocompletion.EntireSequence(pn);
        for (let i = 0; i < children.length; i++) {
            let key = children[i].getSymbol() + ":" + sequence.getNameForChild(i);
            let autocompletionsForChild = this.symbol2Autocompletion.get(key);
            if (autocompletionsForChild !== undefined) {
                entireSequenceCompletion.add(autocompletionsForChild);
                continue;
            }
            const bnf = new BNF_js_1.BNF(this.ebnf.getBNF());
            const newSequence = new Sequence_js_1.Sequence(undefined, children[i]);
            newSequence.setParsedChildNames(sequence.getNameForChild(i));
            newSequence.createBNF(bnf);
            bnf.removeStartProduction();
            bnf.addProduction(new Production_js_1.Production(BNF_js_1.BNF.ARTIFICIAL_START_SYMBOL, newSequence.getTarget()));
            const parser = new RDParser_js_1.RDParser(bnf, new Lexer_js_1.Lexer(""), EBNFParsedNodeFactory_js_1.EBNFParsedNodeFactory.INSTANCE);
            autocompletionsForChild = [];
            parser.parse(autocompletionsForChild);
            this.symbol2Autocompletion.set(key, autocompletionsForChild);
            entireSequenceCompletion.add(autocompletionsForChild);
        }
        // avoid to call getCompletion() more often than necessary
        if (alreadyEntered.length === 0)
            return entireSequenceCompletion.asArray();
        const idx = entireSequenceCompletion.getCompletion(Autocompletion_js_1.Autocompletion.Purpose.FOR_INSERTION).indexOf("${");
        if (idx !== undefined && idx >= 0 && alreadyEntered.length > idx)
            return undefined;
        return entireSequenceCompletion.asArray();
    }
}
exports.EntireSequenceCompleter = EntireSequenceCompleter;
var Autocompleter;
(function (Autocompleter) {
    Autocompleter.DEFAULT_INLINE_AUTOCOMPLETER = {
        getAutocompletion(pn, _justCheck) {
            let alreadyEntered = pn.getParsedString();
            if (alreadyEntered.length > 0)
                return Autocompletion_js_1.Autocompletion.veto(pn);
            let name = pn.getName();
            if (name === undefined)
                name = pn.getSymbol().getSymbol();
            if (name === undefined)
                return undefined;
            return Autocompletion_js_1.Autocompletion.parameterized(pn, name);
        }
    };
})(Autocompleter || (exports.Autocompleter = Autocompleter = {}));
;
//# sourceMappingURL=Autocompleter.js.map