import { assignMandatoryProperties as e, getContainerOfType as t, linkContentToContainer as n } from "../utils/ast-utils.js";
import { isAssignment as r, isCrossReference as i, isInfixRule as a, isKeyword as o, isParserRule as s } from "../languages/generated/ast.js";
import { getTypeName as c, isDataTypeRule as l } from "../utils/grammar-utils.js";
import { defaultParserErrorProvider as u } from "../../../chevrotain/lib/src/parse/errors_public.js";
import { LLkLookaheadStrategy as d } from "../../../chevrotain/lib/src/parse/grammar/llk_lookahead.js";
import { EmbeddedActionsParser as f } from "../../../chevrotain/lib/src/parse/parser/parser.js";
import "../../../chevrotain/lib/src/api.js";
import { LLStarLookaheadStrategy as p } from "../../../chevrotain-allstar/lib/all-star-lookahead.js";
import "../../../chevrotain-allstar/lib/index.js";
import { CstNodeBuilder as m } from "./cst-node-builder.js";
//#region ../../node_modules/langium/lib/parser/langium-parser.js
var h = Symbol("Datatype");
function g(e) {
	return e.$type === h;
}
var _ = "​", v = (e) => e.endsWith(_) ? e : e + _, y = class {
	constructor(e) {
		this._unorderedGroups = /* @__PURE__ */ new Map(), this.allRules = /* @__PURE__ */ new Map(), this.lexer = e.parser.Lexer;
		let t = this.lexer.definition, n = e.LanguageMetaData.mode === "production";
		e.shared.profilers.LangiumProfiler?.isActive("parsing") ? this.wrapper = new E(t, {
			...e.parser.ParserConfig,
			skipValidations: n,
			errorMessageProvider: e.parser.ParserErrorMessageProvider
		}, e.shared.profilers.LangiumProfiler.createTask("parsing", e.LanguageMetaData.languageId)) : this.wrapper = new T(t, {
			...e.parser.ParserConfig,
			skipValidations: n,
			errorMessageProvider: e.parser.ParserErrorMessageProvider
		});
	}
	alternatives(e, t) {
		this.wrapper.wrapOr(e, t);
	}
	optional(e, t) {
		this.wrapper.wrapOption(e, t);
	}
	many(e, t) {
		this.wrapper.wrapMany(e, t);
	}
	atLeastOne(e, t) {
		this.wrapper.wrapAtLeastOne(e, t);
	}
	getRule(e) {
		return this.allRules.get(e);
	}
	isRecording() {
		return this.wrapper.IS_RECORDING;
	}
	get unorderedGroups() {
		return this._unorderedGroups;
	}
	getRuleStack() {
		return this.wrapper.RULE_STACK;
	}
	finalize() {
		this.wrapper.wrapSelfAnalysis();
	}
}, b = class extends y {
	get current() {
		return this.stack[this.stack.length - 1];
	}
	constructor(e) {
		super(e), this.nodeBuilder = new m(), this.stack = [], this.assignmentMap = /* @__PURE__ */ new Map(), this.operatorPrecedence = /* @__PURE__ */ new Map(), this.linker = e.references.Linker, this.converter = e.parser.ValueConverter, this.astReflection = e.shared.AstReflection;
	}
	rule(e, t) {
		let n = this.computeRuleType(e), r;
		a(e) && (r = e.name, this.registerPrecedenceMap(e));
		let i = this.wrapper.DEFINE_RULE(v(e.name), this.startImplementation(n, r, t).bind(this));
		return this.allRules.set(e.name, i), s(e) && e.entry && (this.mainRule = i), i;
	}
	registerPrecedenceMap(e) {
		let t = e.name, n = /* @__PURE__ */ new Map();
		for (let t = 0; t < e.operators.precedences.length; t++) {
			let r = e.operators.precedences[t];
			for (let e of r.operators) n.set(e.value, {
				precedence: t,
				rightAssoc: r.associativity === "right"
			});
		}
		this.operatorPrecedence.set(t, n);
	}
	computeRuleType(e) {
		return a(e) ? c(e) : e.fragment ? void 0 : l(e) ? h : c(e);
	}
	parse(e, t = {}) {
		this.nodeBuilder.buildRootNode(e);
		let r = this.lexerResult = this.lexer.tokenize(e);
		this.wrapper.input = r.tokens;
		let i = t.rule ? this.allRules.get(t.rule) : this.mainRule;
		if (!i) throw Error(t.rule ? `No rule found with name '${t.rule}'` : "No main rule available.");
		let a = this.doParse(i);
		return this.nodeBuilder.addHiddenNodes(r.hidden), this.unorderedGroups.clear(), this.lexerResult = void 0, n(a, { deep: !0 }), {
			value: a,
			lexerErrors: r.errors,
			lexerReport: r.report,
			parserErrors: this.wrapper.errors
		};
	}
	doParse(e) {
		let t = this.wrapper.rule(e);
		if (this.stack.length > 0 && (t = this.construct()), t === void 0) throw Error("No result from parser");
		if (this.stack.length > 0) throw Error("Parser stack is not empty after parsing");
		return t;
	}
	startImplementation(e, t, n) {
		return (r) => {
			let i = !this.isRecording() && e !== void 0;
			if (i) {
				let n = { $type: e };
				this.stack.push(n), e === h ? n.value = "" : t !== void 0 && (n.$infixName = t);
			}
			return n(r), i ? this.construct() : void 0;
		};
	}
	extractHiddenTokens(e) {
		let t = this.lexerResult.hidden;
		if (!t.length) return [];
		let n = e.startOffset;
		for (let e = 0; e < t.length; e++) if (t[e].startOffset > n) return t.splice(0, e);
		return t.splice(0, t.length);
	}
	consume(e, t, n) {
		let r = this.wrapper.wrapConsume(e, t);
		if (!this.isRecording() && this.isValidToken(r)) {
			let e = this.extractHiddenTokens(r);
			this.nodeBuilder.addHiddenNodes(e);
			let t = this.nodeBuilder.buildLeafNode(r, n), { assignment: i, crossRef: a } = this.getAssignment(n), s = this.current;
			if (i) {
				let e = o(n) ? r.image : this.converter.convert(r.image, t);
				this.assign(i.operator, i.feature, e, t, a);
			} else if (g(s)) {
				let e = r.image;
				o(n) || (e = this.converter.convert(e, t).toString()), s.value += e;
			}
		}
	}
	isValidToken(e) {
		return !e.isInsertedInRecovery && !isNaN(e.startOffset) && typeof e.endOffset == "number" && !isNaN(e.endOffset);
	}
	subrule(e, t, n, r, i) {
		let a;
		!this.isRecording() && !n && (a = this.nodeBuilder.buildCompositeNode(r));
		let o;
		try {
			o = this.wrapper.wrapSubrule(e, t, i);
		} finally {
			this.isRecording() || (o === void 0 && !n && (o = this.construct()), o !== void 0 && a && a.length > 0 && this.performSubruleAssignment(o, r, a));
		}
	}
	performSubruleAssignment(e, t, n) {
		let { assignment: r, crossRef: i } = this.getAssignment(t);
		if (r) this.assign(r.operator, r.feature, e, n, i);
		else if (!r) {
			let t = this.current;
			if (g(t)) t.value += e.toString();
			else if (typeof e == "object" && e) {
				let n = this.assignWithoutOverride(e, t);
				this.stack.pop(), this.stack.push(n);
			}
		}
	}
	action(e, t) {
		if (!this.isRecording()) {
			let n = this.current;
			if (t.feature && t.operator) {
				n = this.construct(), this.nodeBuilder.removeNode(n.$cstNode), this.nodeBuilder.buildCompositeNode(t).content.push(n.$cstNode);
				let r = { $type: e };
				this.stack.push(r), this.assign(t.operator, t.feature, n, n.$cstNode);
			} else n.$type = e;
		}
	}
	construct() {
		if (this.isRecording()) return;
		let t = this.stack.pop();
		return this.nodeBuilder.construct(t), "$infixName" in t ? this.constructInfix(t, this.operatorPrecedence.get(t.$infixName)) : g(t) ? this.converter.convert(t.value, t.$cstNode) : (e(this.astReflection, t), t);
	}
	constructInfix(e, t) {
		let n = e.parts;
		if (!Array.isArray(n) || n.length === 0) return;
		let r = e.operators;
		if (!Array.isArray(r) || n.length < 2) return n[0];
		let i = 0, a = -1;
		for (let e = 0; e < r.length; e++) {
			let n = r[e], o = t.get(n) ?? {
				precedence: Infinity,
				rightAssoc: !1
			};
			o.precedence > a ? (a = o.precedence, i = e) : o.precedence === a && (o.rightAssoc || (i = e));
		}
		let o = r.slice(0, i), s = r.slice(i + 1), c = n.slice(0, i + 1), l = n.slice(i + 1), u = {
			$infixName: e.$infixName,
			$type: e.$type,
			$cstNode: e.$cstNode,
			parts: c,
			operators: o
		}, d = {
			$infixName: e.$infixName,
			$type: e.$type,
			$cstNode: e.$cstNode,
			parts: l,
			operators: s
		}, f = this.constructInfix(u, t), p = this.constructInfix(d, t);
		return {
			$type: e.$type,
			$cstNode: e.$cstNode,
			left: f,
			operator: r[i],
			right: p
		};
	}
	getAssignment(e) {
		if (!this.assignmentMap.has(e)) {
			let n = t(e, r);
			this.assignmentMap.set(e, {
				assignment: n,
				crossRef: n && i(n.terminal) ? n.terminal.isMulti ? "multi" : "single" : void 0
			});
		}
		return this.assignmentMap.get(e);
	}
	assign(e, t, n, r, i) {
		let a = this.current, o;
		switch (o = i === "single" && typeof n == "string" ? this.linker.buildReference(a, t, r, n) : i === "multi" && typeof n == "string" ? this.linker.buildMultiReference(a, t, r, n) : n, e) {
			case "=":
				a[t] = o;
				break;
			case "?=":
				a[t] = !0;
				break;
			case "+=": Array.isArray(a[t]) || (a[t] = []), a[t].push(o);
		}
	}
	assignWithoutOverride(e, t) {
		for (let [n, r] of Object.entries(t)) {
			let t = e[n];
			t === void 0 ? e[n] = r : Array.isArray(t) && Array.isArray(r) && (r.push(...t), e[n] = r);
		}
		let n = e.$cstNode;
		return n && (n.astNode = void 0, e.$cstNode = void 0), e;
	}
	get definitionErrors() {
		return this.wrapper.definitionErrors;
	}
}, x = class {
	buildMismatchTokenMessage(e) {
		return u.buildMismatchTokenMessage(e);
	}
	buildNotAllInputParsedMessage(e) {
		return u.buildNotAllInputParsedMessage(e);
	}
	buildNoViableAltMessage(e) {
		return u.buildNoViableAltMessage(e);
	}
	buildEarlyExitMessage(e) {
		return u.buildEarlyExitMessage(e);
	}
}, S = class extends x {
	buildMismatchTokenMessage({ expected: e, actual: t }) {
		return `Expecting ${e.LABEL ? "`" + e.LABEL + "`" : e.name.endsWith(":KW") ? `keyword '${e.name.substring(0, e.name.length - 3)}'` : `token of type '${e.name}'`} but found \`${t.image}\`.`;
	}
	buildNotAllInputParsedMessage({ firstRedundant: e }) {
		return `Expecting end of file but found \`${e.image}\`.`;
	}
}, C = class extends y {
	constructor() {
		super(...arguments), this.tokens = [], this.elementStack = [], this.lastElementStack = [], this.nextTokenIndex = 0, this.stackSize = 0;
	}
	action() {}
	construct() {}
	parse(e) {
		return this.resetState(), this.tokens = this.lexer.tokenize(e, { mode: "partial" }).tokens, this.wrapper.input = [...this.tokens], this.mainRule.call(this.wrapper, {}), this.unorderedGroups.clear(), {
			tokens: this.tokens,
			elementStack: [...this.lastElementStack],
			tokenIndex: this.nextTokenIndex
		};
	}
	rule(e, t) {
		let n = this.wrapper.DEFINE_RULE(v(e.name), this.startImplementation(t).bind(this));
		return this.allRules.set(e.name, n), e.entry && (this.mainRule = n), n;
	}
	resetState() {
		this.elementStack = [], this.lastElementStack = [], this.nextTokenIndex = 0, this.stackSize = 0;
	}
	startImplementation(e) {
		return (t) => {
			let n = this.keepStackSize();
			try {
				e(t);
			} finally {
				this.resetStackSize(n);
			}
		};
	}
	removeUnexpectedElements() {
		this.elementStack.splice(this.stackSize);
	}
	keepStackSize() {
		let e = this.elementStack.length;
		return this.stackSize = e, e;
	}
	resetStackSize(e) {
		this.removeUnexpectedElements(), this.stackSize = e;
	}
	consume(e, t, n) {
		this.wrapper.wrapConsume(e, t), this.isRecording() || (this.lastElementStack = [...this.elementStack, n], this.nextTokenIndex = this.currIdx + 1);
	}
	subrule(e, t, n, r, i) {
		this.before(r), this.wrapper.wrapSubrule(e, t, i), this.after(r);
	}
	before(e) {
		this.isRecording() || this.elementStack.push(e);
	}
	after(e) {
		if (!this.isRecording()) {
			let t = this.elementStack.lastIndexOf(e);
			t >= 0 && this.elementStack.splice(t);
		}
	}
	get currIdx() {
		return this.wrapper.currIdx;
	}
}, w = {
	recoveryEnabled: !0,
	nodeLocationTracking: "full",
	skipValidations: !0,
	errorMessageProvider: new S()
}, T = class extends f {
	constructor(e, t) {
		let n = t && "maxLookahead" in t;
		super(e, {
			...w,
			lookaheadStrategy: n ? new d({ maxLookahead: t.maxLookahead }) : new p({ logging: t.skipValidations ? () => {} : void 0 }),
			...t
		});
	}
	get IS_RECORDING() {
		return this.RECORDING_PHASE;
	}
	DEFINE_RULE(e, t, n) {
		return this.RULE(e, t, n);
	}
	wrapSelfAnalysis() {
		this.performSelfAnalysis();
	}
	wrapConsume(e, t) {
		return this.consume(e, t, void 0);
	}
	wrapSubrule(e, t, n) {
		return this.subrule(e, t, { ARGS: [n] });
	}
	wrapOr(e, t) {
		this.or(e, t);
	}
	wrapOption(e, t) {
		this.option(e, t);
	}
	wrapMany(e, t) {
		this.many(e, t);
	}
	wrapAtLeastOne(e, t) {
		this.atLeastOne(e, t);
	}
	rule(e) {
		return e.call(this, {});
	}
}, E = class extends T {
	constructor(e, t, n) {
		super(e, t), this.task = n;
	}
	rule(e) {
		this.task.start(), this.task.startSubTask(this.ruleName(e));
		try {
			return super.rule(e);
		} finally {
			this.task.stopSubTask(this.ruleName(e)), this.task.stop();
		}
	}
	ruleName(e) {
		return e.ruleName;
	}
	subrule(e, t, n) {
		this.task.startSubTask(this.ruleName(t));
		try {
			return super.subrule(e, t, n);
		} finally {
			this.task.stopSubTask(this.ruleName(t));
		}
	}
};
//#endregion
export { C as LangiumCompletionParser, b as LangiumParser, S as LangiumParserErrorMessageProvider };
