import noop_default from "../../../../../../lodash-es/noop.js";
import keys_default from "../../../../../../lodash-es/keys.js";
import has_default from "../../../../../../lodash-es/has.js";
import isUndefined_default from "../../../../../../lodash-es/isUndefined.js";
import { addNoneTerminalToCst, addTerminalToCst, setNodeLocationFull, setNodeLocationOnlyOffset } from "../../cst/cst.js";
import { createBaseSemanticVisitorConstructor, createBaseVisitorConstructorWithDefaults } from "../../cst/cst_visitor.js";
import { DEFAULT_PARSER_CONFIG } from "../parser.js";
var TreeBuilder = class {
	initTreeBuilder(u) {
		if (this.CST_STACK = [], this.outputCst = u.outputCst, this.nodeLocationTracking = has_default(u, "nodeLocationTracking") ? u.nodeLocationTracking : DEFAULT_PARSER_CONFIG.nodeLocationTracking, !this.outputCst) this.cstInvocationStateUpdate = noop_default, this.cstFinallyStateUpdate = noop_default, this.cstPostTerminal = noop_default, this.cstPostNonTerminal = noop_default, this.cstPostRule = noop_default;
		else if (/full/i.test(this.nodeLocationTracking)) this.recoveryEnabled ? (this.setNodeLocationFromToken = setNodeLocationFull, this.setNodeLocationFromNode = setNodeLocationFull, this.cstPostRule = noop_default, this.setInitialNodeLocation = this.setInitialNodeLocationFullRecovery) : (this.setNodeLocationFromToken = noop_default, this.setNodeLocationFromNode = noop_default, this.cstPostRule = this.cstPostRuleFull, this.setInitialNodeLocation = this.setInitialNodeLocationFullRegular);
		else if (/onlyOffset/i.test(this.nodeLocationTracking)) this.recoveryEnabled ? (this.setNodeLocationFromToken = setNodeLocationOnlyOffset, this.setNodeLocationFromNode = setNodeLocationOnlyOffset, this.cstPostRule = noop_default, this.setInitialNodeLocation = this.setInitialNodeLocationOnlyOffsetRecovery) : (this.setNodeLocationFromToken = noop_default, this.setNodeLocationFromNode = noop_default, this.cstPostRule = this.cstPostRuleOnlyOffset, this.setInitialNodeLocation = this.setInitialNodeLocationOnlyOffsetRegular);
		else if (/none/i.test(this.nodeLocationTracking)) this.setNodeLocationFromToken = noop_default, this.setNodeLocationFromNode = noop_default, this.cstPostRule = noop_default, this.setInitialNodeLocation = noop_default;
		else throw Error(`Invalid <nodeLocationTracking> config option: "${u.nodeLocationTracking}"`);
	}
	setInitialNodeLocationOnlyOffsetRecovery(e) {
		e.location = {
			startOffset: NaN,
			endOffset: NaN
		};
	}
	setInitialNodeLocationOnlyOffsetRegular(e) {
		e.location = {
			startOffset: this.LA(1).startOffset,
			endOffset: NaN
		};
	}
	setInitialNodeLocationFullRecovery(e) {
		e.location = {
			startOffset: NaN,
			startLine: NaN,
			startColumn: NaN,
			endOffset: NaN,
			endLine: NaN,
			endColumn: NaN
		};
	}
	setInitialNodeLocationFullRegular(e) {
		let u = this.LA(1);
		e.location = {
			startOffset: u.startOffset,
			startLine: u.startLine,
			startColumn: u.startColumn,
			endOffset: NaN,
			endLine: NaN,
			endColumn: NaN
		};
	}
	cstInvocationStateUpdate(e) {
		let u = {
			name: e,
			children: Object.create(null)
		};
		this.setInitialNodeLocation(u), this.CST_STACK.push(u);
	}
	cstFinallyStateUpdate() {
		this.CST_STACK.pop();
	}
	cstPostRuleFull(e) {
		let u = this.LA(0), d = e.location;
		d.startOffset <= u.startOffset ? (d.endOffset = u.endOffset, d.endLine = u.endLine, d.endColumn = u.endColumn) : (d.startOffset = NaN, d.startLine = NaN, d.startColumn = NaN);
	}
	cstPostRuleOnlyOffset(e) {
		let u = this.LA(0), d = e.location;
		d.startOffset <= u.startOffset ? d.endOffset = u.endOffset : d.startOffset = NaN;
	}
	cstPostTerminal(e, u) {
		let d = this.CST_STACK[this.CST_STACK.length - 1];
		addTerminalToCst(d, u, e), this.setNodeLocationFromToken(d.location, u);
	}
	cstPostNonTerminal(e, u) {
		let d = this.CST_STACK[this.CST_STACK.length - 1];
		addNoneTerminalToCst(d, u, e), this.setNodeLocationFromNode(d.location, e.location);
	}
	getBaseCstVisitorConstructor() {
		if (isUndefined_default(this.baseCstVisitorConstructor)) {
			let e = createBaseSemanticVisitorConstructor(this.className, keys_default(this.gastProductionsCache));
			return this.baseCstVisitorConstructor = e, e;
		}
		return this.baseCstVisitorConstructor;
	}
	getBaseCstVisitorConstructorWithDefaults() {
		if (isUndefined_default(this.baseCstVisitorWithDefaultsConstructor)) {
			let e = createBaseVisitorConstructorWithDefaults(this.className, keys_default(this.gastProductionsCache), this.getBaseCstVisitorConstructor());
			return this.baseCstVisitorWithDefaultsConstructor = e, e;
		}
		return this.baseCstVisitorWithDefaultsConstructor;
	}
	getLastExplicitRuleShortName() {
		let e = this.RULE_STACK;
		return e[e.length - 1];
	}
	getPreviousExplicitRuleShortName() {
		let e = this.RULE_STACK;
		return e[e.length - 2];
	}
	getLastExplicitRuleOccurrenceIndex() {
		let e = this.RULE_OCCURRENCE_STACK;
		return e[e.length - 1];
	}
};
export { TreeBuilder };
