import { Alternation as e, Alternative as t, NonTerminal as n, Option as r, Repetition as i, RepetitionMandatory as a, RepetitionMandatoryWithSeparator as o, RepetitionWithSeparator as s, Terminal as c } from "../../../../../@chevrotain/gast/lib/src/model.js";
import { GAstVisitor as l } from "../../../../../@chevrotain/gast/lib/src/visitor.js";
import { getProductionDslName as u, isOptionalProd as d } from "../../../../../@chevrotain/gast/lib/src/helpers.js";
import { tokenStructuredMatcher as f } from "../../scan/tokens.js";
import { nextPossibleTokensAfter as p } from "./interpreter.js";
import { containsPath as m, getLookaheadPathsForOptionalProd as h, getLookaheadPathsForOr as g, getProdType as _, isStrictPrefixOfPath as v } from "./lookahead.js";
import { ParserDefinitionErrorType as y } from "../parser/parser.js";
//#region ../../node_modules/chevrotain/lib/src/parse/grammar/checks.js
function b(e) {
	return e.lookaheadStrategy.validate({
		rules: e.rules,
		tokenTypes: e.tokenTypes,
		grammarName: e.grammarName
	}).map((e) => Object.assign({ type: y.CUSTOM_LOOKAHEAD_VALIDATION }, e));
}
function x(e, t, n, r) {
	let i = e.flatMap((e) => S(e, n)), a = R(e, t, n), o = e.flatMap((e) => P(e, n)), s = e.flatMap((t) => E(t, e, r, n));
	return i.concat(a, o, s);
}
function S(e, t) {
	let n = new T();
	e.accept(n);
	let r = n.allProductions, i = Object.groupBy(r, C), a = Object.fromEntries(Object.entries(i).filter(([e, t]) => t.length > 1));
	return Object.values(a).map((n) => {
		let r = n[0], i = t.buildDuplicateFoundError(e, n), a = u(r), o = {
			message: i,
			type: y.DUPLICATE_PRODUCTIONS,
			ruleName: e.name,
			dslName: a,
			occurrence: r.idx
		}, s = w(r);
		return s && (o.parameter = s), o;
	});
}
function C(e) {
	return `${u(e)}_#_${e.idx}_#_${w(e)}`;
}
function w(e) {
	return e instanceof c ? e.terminalType.name : e instanceof n ? e.nonTerminalName : "";
}
var T = class extends l {
	constructor() {
		super(...arguments), this.allProductions = [];
	}
	visitNonTerminal(e) {
		this.allProductions.push(e);
	}
	visitOption(e) {
		this.allProductions.push(e);
	}
	visitRepetitionWithSeparator(e) {
		this.allProductions.push(e);
	}
	visitRepetitionMandatory(e) {
		this.allProductions.push(e);
	}
	visitRepetitionMandatoryWithSeparator(e) {
		this.allProductions.push(e);
	}
	visitRepetition(e) {
		this.allProductions.push(e);
	}
	visitAlternation(e) {
		this.allProductions.push(e);
	}
	visitTerminal(e) {
		this.allProductions.push(e);
	}
};
function E(e, t, n, r) {
	let i = [];
	if (t.reduce((t, n) => n.name === e.name ? t + 1 : t, 0) > 1) {
		let t = r.buildDuplicateRuleNameError({
			topLevelRule: e,
			grammarName: n
		});
		i.push({
			message: t,
			type: y.DUPLICATE_RULE_NAME,
			ruleName: e.name
		});
	}
	return i;
}
function D(e, t, n) {
	let r = [], i;
	return t.includes(e) || (i = `Invalid rule override, rule: ->${e}<- cannot be overridden in the grammar: ->${n}<-as it is not defined in any of the super grammars `, r.push({
		message: i,
		type: y.INVALID_RULE_OVERRIDE,
		ruleName: e
	})), r;
}
function O(e, t, n, r = []) {
	let i = [], a = k(t.definition);
	if (a.length === 0) return [];
	{
		let t = e.name;
		a.includes(e) && i.push({
			message: n.buildLeftRecursionError({
				topLevelRule: e,
				leftRecursionPath: r
			}),
			type: y.LEFT_RECURSION,
			ruleName: t
		});
		let o = r.concat([e]), s = a.filter((e) => !o.includes(e)).flatMap((t) => {
			let i = [...r];
			return i.push(t), O(e, t, n, i);
		});
		return i.concat(s);
	}
}
function k(l) {
	let u = [];
	if (l.length === 0) return u;
	let f = l[0];
	/* istanbul ignore else */
	if (f instanceof n) u.push(f.referencedRule);
	else if (f instanceof t || f instanceof r || f instanceof a || f instanceof o || f instanceof s || f instanceof i) u = u.concat(k(f.definition));
	else if (f instanceof e) u = f.definition.map((e) => k(e.definition)).flat();
	else if (!(f instanceof c)) throw Error("non exhaustive match");
	let p = d(f), m = l.length > 1;
	if (p && m) {
		let e = l.slice(1);
		return u.concat(k(e));
	} else return u;
}
var A = class extends l {
	constructor() {
		super(...arguments), this.alternations = [];
	}
	visitAlternation(e) {
		this.alternations.push(e);
	}
};
function j(e, t) {
	let n = new A();
	return e.accept(n), n.alternations.flatMap((n) => n.definition.slice(0, -1).flatMap((r, i) => p([r], [], f, 1).length === 0 ? [{
		message: t.buildEmptyAlternationError({
			topLevelRule: e,
			alternation: n,
			emptyChoiceIdx: i
		}),
		type: y.NONE_LAST_EMPTY_ALT,
		ruleName: e.name,
		occurrence: n.idx,
		alternative: i + 1
	}] : []));
}
function M(e, t, n) {
	let r = new A();
	e.accept(r);
	let i = r.alternations;
	return i = i.filter((e) => e.ignoreAmbiguities !== !0), i.flatMap((r) => {
		let i = r.idx, a = g(i, e, r.maxLookahead || t, r), o = I(a, r, e, n), s = L(a, r, e, n);
		return o.concat(s);
	});
}
var N = class extends l {
	constructor() {
		super(...arguments), this.allProductions = [];
	}
	visitRepetitionWithSeparator(e) {
		this.allProductions.push(e);
	}
	visitRepetitionMandatory(e) {
		this.allProductions.push(e);
	}
	visitRepetitionMandatoryWithSeparator(e) {
		this.allProductions.push(e);
	}
	visitRepetition(e) {
		this.allProductions.push(e);
	}
};
function P(e, t) {
	let n = new A();
	return e.accept(n), n.alternations.flatMap((n) => n.definition.length > 255 ? [{
		message: t.buildTooManyAlternativesError({
			topLevelRule: e,
			alternation: n
		}),
		type: y.TOO_MANY_ALTS,
		ruleName: e.name,
		occurrence: n.idx
	}] : []);
}
function F(e, t, n) {
	let r = [];
	return e.forEach((e) => {
		let i = new N();
		e.accept(i), i.allProductions.forEach((i) => {
			let a = _(i), o = i.maxLookahead || t, s = i.idx;
			if (h(s, e, a, o)[0].flat().length === 0) {
				let t = n.buildEmptyRepetitionError({
					topLevelRule: e,
					repetition: i
				});
				r.push({
					message: t,
					type: y.NO_NON_EMPTY_LOOKAHEAD,
					ruleName: e.name
				});
			}
		});
	}), r;
}
function I(e, t, n, r) {
	let i = [];
	return e.reduce((n, r, a) => (t.definition[a].ignoreAmbiguities === !0 || r.forEach((r) => {
		let o = [a];
		e.forEach((e, n) => {
			a !== n && m(e, r) && t.definition[n].ignoreAmbiguities !== !0 && o.push(n);
		}), o.length > 1 && !m(i, r) && (i.push(r), n.push({
			alts: o,
			path: r
		}));
	}), n), []).map((e) => {
		let i = e.alts.map((e) => e + 1);
		return {
			message: r.buildAlternationAmbiguityError({
				topLevelRule: n,
				alternation: t,
				ambiguityIndices: i,
				prefixPath: e.path
			}),
			type: y.AMBIGUOUS_ALTS,
			ruleName: n.name,
			occurrence: t.idx,
			alternatives: e.alts
		};
	});
}
function L(e, t, n, r) {
	let i = e.reduce((e, t, n) => {
		let r = t.map((e) => ({
			idx: n,
			path: e
		}));
		return e.concat(r);
	}, []);
	return i.flatMap((e) => {
		if (t.definition[e.idx].ignoreAmbiguities === !0) return [];
		let a = e.idx, o = e.path;
		return i.filter((e) => t.definition[e.idx].ignoreAmbiguities !== !0 && e.idx < a && v(e.path, o)).map((e) => {
			let i = [e.idx + 1, a + 1], o = t.idx === 0 ? "" : t.idx;
			return {
				message: r.buildAlternationPrefixAmbiguityError({
					topLevelRule: n,
					alternation: t,
					ambiguityIndices: i,
					prefixPath: e.path
				}),
				type: y.AMBIGUOUS_PREFIX_ALTS,
				ruleName: n.name,
				occurrence: o,
				alternatives: i
			};
		});
	});
}
function R(e, t, n) {
	let r = [], i = t.map((e) => e.name);
	return e.forEach((e) => {
		let t = e.name;
		if (i.includes(t)) {
			let i = n.buildNamespaceConflictError(e);
			r.push({
				message: i,
				type: y.CONFLICT_TOKENS_RULES_NAMESPACE,
				ruleName: t
			});
		}
	}), r;
}
//#endregion
export { M as validateAmbiguousAlternationAlternatives, j as validateEmptyOrAlternative, x as validateGrammar, b as validateLookahead, O as validateNoLeftRecursion, D as validateRuleIsOverridden, F as validateSomeNonEmptyLookaheadPath };
