'use strict';

var errors_public = require('../errors_public.js');
var parser = require('../parser/parser.js');
var checks = require('./checks.js');
var lookahead = require('./lookahead.js');
var isEmpty = require('../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isEmpty.js');
var flatMap = require('../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/flatMap.js');

class LLkLookaheadStrategy {
    constructor(options) {
        var _a;
        this.maxLookahead =
            (_a = options === null || options === void 0 ? void 0 : options.maxLookahead) !== null && _a !== void 0 ? _a : parser.DEFAULT_PARSER_CONFIG.maxLookahead;
    }
    validate(options) {
        const leftRecursionErrors = this.validateNoLeftRecursion(options.rules);
        if (isEmpty.default(leftRecursionErrors)) {
            const emptyAltErrors = this.validateEmptyOrAlternatives(options.rules);
            const ambiguousAltsErrors = this.validateAmbiguousAlternationAlternatives(options.rules, this.maxLookahead);
            const emptyRepetitionErrors = this.validateSomeNonEmptyLookaheadPath(options.rules, this.maxLookahead);
            const allErrors = [
                ...leftRecursionErrors,
                ...emptyAltErrors,
                ...ambiguousAltsErrors,
                ...emptyRepetitionErrors,
            ];
            return allErrors;
        }
        return leftRecursionErrors;
    }
    validateNoLeftRecursion(rules) {
        return flatMap.default(rules, (currTopRule) => checks.validateNoLeftRecursion(currTopRule, currTopRule, errors_public.defaultGrammarValidatorErrorProvider));
    }
    validateEmptyOrAlternatives(rules) {
        return flatMap.default(rules, (currTopRule) => checks.validateEmptyOrAlternative(currTopRule, errors_public.defaultGrammarValidatorErrorProvider));
    }
    validateAmbiguousAlternationAlternatives(rules, maxLookahead) {
        return flatMap.default(rules, (currTopRule) => checks.validateAmbiguousAlternationAlternatives(currTopRule, maxLookahead, errors_public.defaultGrammarValidatorErrorProvider));
    }
    validateSomeNonEmptyLookaheadPath(rules, maxLookahead) {
        return checks.validateSomeNonEmptyLookaheadPath(rules, maxLookahead, errors_public.defaultGrammarValidatorErrorProvider);
    }
    buildLookaheadForAlternation(options) {
        return lookahead.buildLookaheadFuncForOr(options.prodOccurrence, options.rule, options.maxLookahead, options.hasPredicates, options.dynamicTokensEnabled, lookahead.buildAlternativesLookAheadFunc);
    }
    buildLookaheadForOptional(options) {
        return lookahead.buildLookaheadFuncForOptionalProd(options.prodOccurrence, options.rule, options.maxLookahead, options.dynamicTokensEnabled, lookahead.getProdType(options.prodType), lookahead.buildSingleAlternativeLookaheadFunction);
    }
}

exports.LLkLookaheadStrategy = LLkLookaheadStrategy;
