import { tokenToRange as e } from "../utils/cst-utils.js";
import { Position as t, init_main as n } from "../../../vscode-languageserver-types/lib/esm/main.js";
//#region ../../node_modules/langium/lib/parser/cst-node-builder.js
n();
var r = class {
	constructor() {
		this.nodeStack = [];
	}
	get current() {
		return this.nodeStack[this.nodeStack.length - 1] ?? this.rootNode;
	}
	buildRootNode(e) {
		return this.rootNode = new c(e), this.rootNode.root = this.rootNode, this.nodeStack = [this.rootNode], this.rootNode;
	}
	buildCompositeNode(e) {
		let t = new o();
		return t.grammarSource = e, t.root = this.rootNode, this.current.content.push(t), this.nodeStack.push(t), t;
	}
	buildLeafNode(t, n) {
		let r = new a(t.startOffset, t.image.length, e(t), t.tokenType, !n);
		return r.grammarSource = n, r.root = this.rootNode, this.current.content.push(r), r;
	}
	removeNode(e) {
		let t = e.container;
		if (t) {
			let n = t.content.indexOf(e);
			n >= 0 && t.content.splice(n, 1);
		}
	}
	addHiddenNodes(t) {
		let n = [];
		for (let r of t) {
			let t = new a(r.startOffset, r.image.length, e(r), r.tokenType, !0);
			t.root = this.rootNode, n.push(t);
		}
		let r = this.current, i = !1;
		if (r.content.length > 0) {
			r.content.push(...n);
			return;
		}
		for (; r.container;) {
			let e = r.container.content.indexOf(r);
			if (e > 0) {
				r.container.content.splice(e, 0, ...n), i = !0;
				break;
			}
			r = r.container;
		}
		i || this.rootNode.content.unshift(...n);
	}
	construct(e) {
		let t = this.current;
		typeof e.$type == "string" && !e.$infixName && (this.current.astNode = e), e.$cstNode = t;
		let n = this.nodeStack.pop();
		n?.content.length === 0 && this.removeNode(n);
	}
}, i = class {
	get hidden() {
		return !1;
	}
	get astNode() {
		let e = typeof this._astNode?.$type == "string" ? this._astNode : this.container?.astNode;
		if (!e) throw Error("This node has no associated AST element");
		return e;
	}
	set astNode(e) {
		this._astNode = e;
	}
	get text() {
		return this.root.fullText.substring(this.offset, this.end);
	}
}, a = class extends i {
	get offset() {
		return this._offset;
	}
	get length() {
		return this._length;
	}
	get end() {
		return this._offset + this._length;
	}
	get hidden() {
		return this._hidden;
	}
	get tokenType() {
		return this._tokenType;
	}
	get range() {
		return this._range;
	}
	constructor(e, t, n, r, i = !1) {
		super(), this._hidden = i, this._offset = e, this._tokenType = r, this._length = t, this._range = n;
	}
}, o = class extends i {
	constructor() {
		super(...arguments), this.content = new s(this);
	}
	get offset() {
		return this.firstNonHiddenNode?.offset ?? 0;
	}
	get length() {
		return this.end - this.offset;
	}
	get end() {
		return this.lastNonHiddenNode?.end ?? 0;
	}
	get range() {
		let e = this.firstNonHiddenNode, n = this.lastNonHiddenNode;
		if (e && n) {
			if (this._rangeCache === void 0) {
				let { range: t } = e, { range: r } = n;
				this._rangeCache = {
					start: t.start,
					end: r.end.line < t.start.line ? t.start : r.end
				};
			}
			return this._rangeCache;
		} else return {
			start: t.create(0, 0),
			end: t.create(0, 0)
		};
	}
	get firstNonHiddenNode() {
		for (let e of this.content) if (!e.hidden) return e;
		return this.content[0];
	}
	get lastNonHiddenNode() {
		for (let e = this.content.length - 1; e >= 0; e--) {
			let t = this.content[e];
			if (!t.hidden) return t;
		}
		return this.content[this.content.length - 1];
	}
}, s = class e extends Array {
	constructor(t) {
		super(), this.parent = t, Object.setPrototypeOf(this, e.prototype);
	}
	push(...e) {
		return this.addParents(e), super.push(...e);
	}
	unshift(...e) {
		return this.addParents(e), super.unshift(...e);
	}
	splice(e, t, ...n) {
		return this.addParents(n), super.splice(e, t, ...n);
	}
	addParents(e) {
		for (let t of e) t.container = this.parent;
	}
}, c = class extends o {
	get text() {
		return this._text.substring(this.offset, this.end);
	}
	get fullText() {
		return this._text;
	}
	constructor(e) {
		super(), this._text = "", this._text = e ?? "";
	}
};
//#endregion
export { o as CompositeCstNodeImpl, r as CstNodeBuilder, a as LeafCstNodeImpl, c as RootCstNodeImpl };
