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, Rule as c, Terminal as l } from "../../../../../@chevrotain/gast/lib/src/model.js";
import { RestWalker as u } from "./rest.js";
import { first as d } from "./first.js";
//#region ../../node_modules/chevrotain/lib/src/parse/grammar/interpreter.js
var f = class extends u {
	constructor(e, t) {
		super(), this.topProd = e, this.path = t, this.possibleTokTypes = [], this.nextProductionName = "", this.nextProductionOccurrence = 0, this.found = !1, this.isAtEndOfPath = !1;
	}
	startWalking() {
		if (this.found = !1, this.path.ruleStack[0] !== this.topProd.name) throw Error("The path does not start with the walker's top Rule!");
		return this.ruleStack = [...this.path.ruleStack].reverse(), this.occurrenceStack = [...this.path.occurrenceStack].reverse(), this.ruleStack.pop(), this.occurrenceStack.pop(), this.updateExpectedNext(), this.walk(this.topProd), this.possibleTokTypes;
	}
	walk(e, t = []) {
		this.found || super.walk(e, t);
	}
	walkProdRef(e, t, n) {
		if (e.referencedRule.name === this.nextProductionName && e.idx === this.nextProductionOccurrence) {
			let r = t.concat(n);
			this.updateExpectedNext(), this.walk(e.referencedRule, r);
		}
	}
	updateExpectedNext() {
		this.ruleStack.length === 0 ? (this.nextProductionName = "", this.nextProductionOccurrence = 0, this.isAtEndOfPath = !0) : (this.nextProductionName = this.ruleStack.pop(), this.nextProductionOccurrence = this.occurrenceStack.pop());
	}
}, p = class extends f {
	constructor(e, t) {
		super(e, t), this.path = t, this.nextTerminalName = "", this.nextTerminalOccurrence = 0, this.nextTerminalName = this.path.lastTok.name, this.nextTerminalOccurrence = this.path.lastTokOccurrence;
	}
	walkTerminal(e, n, r) {
		this.isAtEndOfPath && e.terminalType.name === this.nextTerminalName && e.idx === this.nextTerminalOccurrence && !this.found && (this.possibleTokTypes = d(new t({ definition: n.concat(r) })), this.found = !0);
	}
}, m = class extends u {
	constructor(e, t) {
		super(), this.topRule = e, this.occurrence = t, this.result = {
			token: void 0,
			occurrence: void 0,
			isEndOfRule: void 0
		};
	}
	startWalking() {
		return this.walk(this.topRule), this.result;
	}
}, h = class extends m {
	walkMany(e, t, n) {
		if (e.idx === this.occurrence) {
			let e = t.concat(n)[0];
			this.result.isEndOfRule = e === void 0, e instanceof l && (this.result.token = e.terminalType, this.result.occurrence = e.idx);
		} else super.walkMany(e, t, n);
	}
}, g = class extends m {
	walkManySep(e, t, n) {
		if (e.idx === this.occurrence) {
			let e = t.concat(n)[0];
			this.result.isEndOfRule = e === void 0, e instanceof l && (this.result.token = e.terminalType, this.result.occurrence = e.idx);
		} else super.walkManySep(e, t, n);
	}
}, _ = class extends m {
	walkAtLeastOne(e, t, n) {
		if (e.idx === this.occurrence) {
			let e = t.concat(n)[0];
			this.result.isEndOfRule = e === void 0, e instanceof l && (this.result.token = e.terminalType, this.result.occurrence = e.idx);
		} else super.walkAtLeastOne(e, t, n);
	}
}, v = class extends m {
	walkAtLeastOneSep(e, t, n) {
		if (e.idx === this.occurrence) {
			let e = t.concat(n)[0];
			this.result.isEndOfRule = e === void 0, e instanceof l && (this.result.token = e.terminalType, this.result.occurrence = e.idx);
		} else super.walkAtLeastOneSep(e, t, n);
	}
};
function y(c, u, d = []) {
	d = [...d];
	let f = [], p = 0;
	function m(e) {
		return e.concat(c.slice(p + 1));
	}
	function h(e) {
		let t = y(m(e), u, d);
		return f.concat(t);
	}
	for (; d.length < u && p < c.length;) {
		let u = c[p];
		if (u instanceof t || u instanceof n) return h(u.definition);
		if (u instanceof r) f = h(u.definition);
		else if (u instanceof a) return h(u.definition.concat([new i({ definition: u.definition })]));
		else if (u instanceof o) return h([new t({ definition: u.definition }), new i({ definition: [new l({ terminalType: u.separator })].concat(u.definition) })]);
		else if (u instanceof s) f = h(u.definition.concat([new i({ definition: [new l({ terminalType: u.separator })].concat(u.definition) })]));
		else if (u instanceof i) f = h(u.definition.concat([new i({ definition: u.definition })]));
		else if (u instanceof e) return u.definition.forEach((e) => {
			e.definition.length !== 0 && (f = h(e.definition));
		}), f;
		else if (u instanceof l) d.push(u.terminalType);
		else throw Error("non exhaustive match");
		p++;
	}
	return f.push({
		partialPath: d,
		suffixDef: c.slice(p)
	}), f;
}
function b(u, d, f, p) {
	let m = "EXIT_NONE_TERMINAL", h = [m], g = "EXIT_ALTERNATIVE", _ = !1, v = d.length, y = v - p - 1, b = [], S = [];
	for (S.push({
		idx: -1,
		def: u,
		ruleStack: [],
		occurrenceStack: []
	}); S.length !== 0;) {
		let u = S.pop();
		if (u === g) {
			_ && S.at(-1).idx <= y && S.pop();
			continue;
		}
		let p = u.def, C = u.idx, w = u.ruleStack, T = u.occurrenceStack;
		if (p.length === 0) continue;
		let E = p[0];
		/* istanbul ignore else */
		if (E === m) {
			let e = {
				idx: C,
				def: p.slice(1),
				ruleStack: w.slice(0, -1),
				occurrenceStack: T.slice(0, -1)
			};
			S.push(e);
		} else if (E instanceof l)
 /* istanbul ignore else */
		if (C < v - 1) {
			let e = C + 1, t = d[e];
			if (f(t, E.terminalType)) {
				let t = {
					idx: e,
					def: p.slice(1),
					ruleStack: w,
					occurrenceStack: T
				};
				S.push(t);
			}
		} else if (C === v - 1) b.push({
			nextTokenType: E.terminalType,
			nextTokenOccurrence: E.idx,
			ruleStack: w,
			occurrenceStack: T
		}), _ = !0;
		else throw Error("non exhaustive match");
		else if (E instanceof n) {
			let e = [...w];
			e.push(E.nonTerminalName);
			let t = [...T];
			t.push(E.idx);
			let n = {
				idx: C,
				def: E.definition.concat(h, p.slice(1)),
				ruleStack: e,
				occurrenceStack: t
			};
			S.push(n);
		} else if (E instanceof r) {
			let e = {
				idx: C,
				def: p.slice(1),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(e), S.push(g);
			let t = {
				idx: C,
				def: E.definition.concat(p.slice(1)),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(t);
		} else if (E instanceof a) {
			let e = new i({
				definition: E.definition,
				idx: E.idx
			}), t = {
				idx: C,
				def: E.definition.concat([e], p.slice(1)),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(t);
		} else if (E instanceof o) {
			let e = new i({
				definition: [new l({ terminalType: E.separator })].concat(E.definition),
				idx: E.idx
			}), t = {
				idx: C,
				def: E.definition.concat([e], p.slice(1)),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(t);
		} else if (E instanceof s) {
			let e = {
				idx: C,
				def: p.slice(1),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(e), S.push(g);
			let t = new i({
				definition: [new l({ terminalType: E.separator })].concat(E.definition),
				idx: E.idx
			}), n = {
				idx: C,
				def: E.definition.concat([t], p.slice(1)),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(n);
		} else if (E instanceof i) {
			let e = {
				idx: C,
				def: p.slice(1),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(e), S.push(g);
			let t = new i({
				definition: E.definition,
				idx: E.idx
			}), n = {
				idx: C,
				def: E.definition.concat([t], p.slice(1)),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(n);
		} else if (E instanceof e) for (let e = E.definition.length - 1; e >= 0; e--) {
			let t = {
				idx: C,
				def: E.definition[e].definition.concat(p.slice(1)),
				ruleStack: w,
				occurrenceStack: T
			};
			S.push(t), S.push(g);
		}
		else if (E instanceof t) S.push({
			idx: C,
			def: E.definition.concat(p.slice(1)),
			ruleStack: w,
			occurrenceStack: T
		});
		else if (E instanceof c) S.push(x(E, C, w, T));
		else throw Error("non exhaustive match");
	}
	return b;
}
function x(e, t, n, r) {
	let i = [...n];
	i.push(e.name);
	let a = [...r];
	return a.push(1), {
		idx: t,
		def: e.definition,
		ruleStack: i,
		occurrenceStack: a
	};
}
//#endregion
export { p as NextAfterTokenWalker, v as NextTerminalAfterAtLeastOneSepWalker, _ as NextTerminalAfterAtLeastOneWalker, g as NextTerminalAfterManySepWalker, h as NextTerminalAfterManyWalker, b as nextPossibleTokensAfter, y as possiblePathsFrom };
