import { Autocompletion } from "./core/Autocompletion.js";
import { BNF } from "./core/BNF.js";
import { Lexer } from "./core/Lexer.js";
import { Production } from "./core/Production.js";
import { RDParser } from "./core/RDParser.js";
import { EBNFParsedNodeFactory } from "./ebnf/EBNFParsedNodeFactory.js";
import { Sequence } from "./ebnf/Sequence.js";
class IfNothingYetEnteredAutocompleter {
    constructor(ifNothingYetEntered, otherwise) {
        this.ifNothingYetEntered = ifNothingYetEntered;
        this.otherwise = otherwise;
    }
    getAutocompletion(pn, _justCheck) {
        if (pn.getParsedString().length === 0)
            return Autocompletion.literal(pn, [this.ifNothingYetEntered]);
        if (this.otherwise !== undefined)
            return Autocompletion.literal(pn, [this.otherwise]);
        return undefined;
    }
}
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.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(this.ebnf.getBNF());
            const newSequence = new Sequence(undefined, children[i]);
            newSequence.setParsedChildNames(sequence.getNameForChild(i));
            newSequence.createBNF(bnf);
            bnf.removeStartProduction();
            bnf.addProduction(new Production(BNF.ARTIFICIAL_START_SYMBOL, newSequence.getTarget()));
            const parser = new RDParser(bnf, new Lexer(""), 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.Purpose.FOR_INSERTION).indexOf("${");
        if (idx !== undefined && idx >= 0 && alreadyEntered.length > idx)
            return undefined;
        return entireSequenceCompletion.asArray();
    }
}
var Autocompleter;
(function (Autocompleter) {
    Autocompleter.DEFAULT_INLINE_AUTOCOMPLETER = {
        getAutocompletion(pn, _justCheck) {
            let alreadyEntered = pn.getParsedString();
            if (alreadyEntered.length > 0)
                return Autocompletion.veto(pn);
            let name = pn.getName();
            if (name === undefined)
                name = pn.getSymbol().getSymbol();
            if (name === undefined)
                return undefined;
            return Autocompletion.parameterized(pn, name);
        }
    };
})(Autocompleter || (Autocompleter = {}));
;
export { Autocompleter, EntireSequenceCompleter, IfNothingYetEnteredAutocompleter };
//# sourceMappingURL=Autocompleter.js.map