import { ParserDefinitionErrorType } from '../parser/parser.mjs';
import { GAstVisitor } from '../../../../../../../@chevrotain_gast@11.0.3/node_modules/@chevrotain/gast/lib/src/visitor.mjs';
import forEach from '../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/forEach.mjs';
import values from '../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/values.mjs';

function resolveGrammar(topLevels, errMsgProvider) {
    const refResolver = new GastRefResolverVisitor(topLevels, errMsgProvider);
    refResolver.resolveRefs();
    return refResolver.errors;
}
class GastRefResolverVisitor extends GAstVisitor {
    constructor(nameToTopRule, errMsgProvider) {
        super();
        this.nameToTopRule = nameToTopRule;
        this.errMsgProvider = errMsgProvider;
        this.errors = [];
    }
    resolveRefs() {
        forEach(values(this.nameToTopRule), (prod) => {
            this.currTopLevel = prod;
            prod.accept(this);
        });
    }
    visitNonTerminal(node) {
        const ref = this.nameToTopRule[node.nonTerminalName];
        if (!ref) {
            const msg = this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel, node);
            this.errors.push({
                message: msg,
                type: ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,
                ruleName: this.currTopLevel.name,
                unresolvedRefName: node.nonTerminalName,
            });
        }
        else {
            node.referencedRule = ref;
        }
    }
}

export { GastRefResolverVisitor, resolveGrammar };
