import { PRINT_WARNING as e } from "../../../../@chevrotain/utils/lib/src/print.js";
import { timer as t } from "../../../../@chevrotain/utils/lib/src/timer.js";
import { toFastProperties as n } from "../../../../@chevrotain/utils/lib/src/to-fast-properties.js";
import { clearRegExpParserCache as r } from "./reg_exp_parser.js";
import { DEFAULT_MODE as i, LineTerminatorOptimizedTester as a, analyzeTokenTypes as o, charCodeToOptimizedIndex as s, cloneEmptyGroups as c, performRuntimeChecks as l, performWarningRuntimeChecks as u, validatePatterns as d } from "./lexer.js";
import { augmentTokenTypes as f } from "./tokens.js";
import { defaultLexerErrorProvider as p } from "./lexer_errors_public.js";
//#region ../../node_modules/chevrotain/lib/src/scan/lexer_public.js
var m;
(function(e) {
	e[e.MISSING_PATTERN = 0] = "MISSING_PATTERN", e[e.INVALID_PATTERN = 1] = "INVALID_PATTERN", e[e.EOI_ANCHOR_FOUND = 2] = "EOI_ANCHOR_FOUND", e[e.UNSUPPORTED_FLAGS_FOUND = 3] = "UNSUPPORTED_FLAGS_FOUND", e[e.DUPLICATE_PATTERNS_FOUND = 4] = "DUPLICATE_PATTERNS_FOUND", e[e.INVALID_GROUP_TYPE_FOUND = 5] = "INVALID_GROUP_TYPE_FOUND", e[e.PUSH_MODE_DOES_NOT_EXIST = 6] = "PUSH_MODE_DOES_NOT_EXIST", e[e.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE = 7] = "MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE", e[e.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY = 8] = "MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY", e[e.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST = 9] = "MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST", e[e.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED = 10] = "LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED", e[e.SOI_ANCHOR_FOUND = 11] = "SOI_ANCHOR_FOUND", e[e.EMPTY_MATCH_PATTERN = 12] = "EMPTY_MATCH_PATTERN", e[e.NO_LINE_BREAKS_FLAGS = 13] = "NO_LINE_BREAKS_FLAGS", e[e.UNREACHABLE_PATTERN = 14] = "UNREACHABLE_PATTERN", e[e.IDENTIFY_TERMINATOR = 15] = "IDENTIFY_TERMINATOR", e[e.CUSTOM_LINE_BREAK = 16] = "CUSTOM_LINE_BREAK", e[e.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE = 17] = "MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE";
})(m ||= {});
var h = {
	deferDefinitionErrorsHandling: !1,
	positionTracking: "full",
	lineTerminatorsPattern: /\n|\r\n?/g,
	lineTerminatorCharacters: ["\n", "\r"],
	ensureOptimizations: !1,
	safeMode: !1,
	errorMessageProvider: p,
	traceInitPerf: !1,
	skipValidations: !1,
	recoveryEnabled: !0
};
Object.freeze(h);
var g = class {
	constructor(s, c = h) {
		if (this.lexerDefinition = s, this.lexerDefinitionErrors = [], this.lexerDefinitionWarning = [], this.patternIdxToConfig = {}, this.charCodeToPatternIdxToConfig = {}, this.modes = [], this.emptyGroups = {}, this.trackStartLines = !0, this.trackEndLines = !0, this.hasCustom = !1, this.canModeBeOptimized = {}, this.TRACE_INIT = (e, n) => {
			if (this.traceInitPerf === !0) {
				this.traceInitIndent++;
				let r = Array(this.traceInitIndent + 1).join("	");
				this.traceInitIndent < this.traceInitMaxIdent && console.log(`${r}--> <${e}>`);
				let { time: i, value: a } = t(n), o = i > 10 ? console.warn : console.log;
				return this.traceInitIndent < this.traceInitMaxIdent && o(`${r}<-- <${e}> time: ${i}ms`), this.traceInitIndent--, a;
			} else return n();
		}, typeof c == "boolean") throw Error("The second argument to the Lexer constructor is now an ILexerConfig Object.\na boolean 2nd argument is no longer supported");
		this.config = Object.assign({}, h, c);
		let p = this.config.traceInitPerf;
		p === !0 ? (this.traceInitMaxIdent = Infinity, this.traceInitPerf = !0) : typeof p == "number" && (this.traceInitMaxIdent = p, this.traceInitPerf = !0), this.traceInitIndent = -1, this.TRACE_INIT("Lexer Constructor", () => {
			let t, p = !0;
			this.TRACE_INIT("Lexer Config handling", () => {
				if (this.config.lineTerminatorsPattern === h.lineTerminatorsPattern) this.config.lineTerminatorsPattern = a;
				else if (this.config.lineTerminatorCharacters === h.lineTerminatorCharacters) throw Error("Error: Missing <lineTerminatorCharacters> property on the Lexer config.\n	For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS");
				if (c.safeMode && c.ensureOptimizations) throw Error("\"safeMode\" and \"ensureOptimizations\" flags are mutually exclusive.");
				this.trackStartLines = /full|onlyStart/i.test(this.config.positionTracking), this.trackEndLines = /full/i.test(this.config.positionTracking), Array.isArray(s) ? t = {
					modes: { defaultMode: [...s] },
					defaultMode: i
				} : (p = !1, t = Object.assign({}, s));
			}), this.config.skipValidations === !1 && (this.TRACE_INIT("performRuntimeChecks", () => {
				this.lexerDefinitionErrors = this.lexerDefinitionErrors.concat(l(t, this.trackStartLines, this.config.lineTerminatorCharacters));
			}), this.TRACE_INIT("performWarningRuntimeChecks", () => {
				this.lexerDefinitionWarning = this.lexerDefinitionWarning.concat(u(t, this.trackStartLines, this.config.lineTerminatorCharacters));
			})), t.modes = t.modes ? t.modes : {}, Object.entries(t.modes).forEach(([e, n]) => {
				t.modes[e] = n.filter((e) => e !== void 0);
			});
			let m = Object.keys(t.modes);
			if (Object.entries(t.modes).forEach(([e, t]) => {
				this.TRACE_INIT(`Mode: <${e}> processing`, () => {
					if (this.modes.push(e), this.config.skipValidations === !1 && this.TRACE_INIT("validatePatterns", () => {
						this.lexerDefinitionErrors = this.lexerDefinitionErrors.concat(d(t, m));
					}), this.lexerDefinitionErrors.length === 0) {
						f(t);
						let n;
						this.TRACE_INIT("analyzeTokenTypes", () => {
							n = o(t, {
								lineTerminatorCharacters: this.config.lineTerminatorCharacters,
								positionTracking: c.positionTracking,
								ensureOptimizations: c.ensureOptimizations,
								safeMode: c.safeMode,
								tracer: this.TRACE_INIT
							});
						}), this.patternIdxToConfig[e] = n.patternIdxToConfig, this.charCodeToPatternIdxToConfig[e] = n.charCodeToPatternIdxToConfig, this.emptyGroups = Object.assign({}, this.emptyGroups, n.emptyGroups), this.hasCustom = n.hasCustom || this.hasCustom, this.canModeBeOptimized[e] = n.canBeOptimized;
					}
				});
			}), this.defaultMode = t.defaultMode, this.lexerDefinitionErrors.length > 0 && !this.config.deferDefinitionErrorsHandling) {
				let e = this.lexerDefinitionErrors.map((e) => e.message).join("-----------------------\n");
				throw Error("Errors detected in definition of Lexer:\n" + e);
			}
			this.lexerDefinitionWarning.forEach((t) => {
				e(t.message);
			}), this.TRACE_INIT("Choosing sub-methods implementations", () => {
				if (p && (this.handleModes = () => {}), this.trackStartLines === !1 && (this.computeNewColumn = (e) => e), this.trackEndLines === !1 && (this.updateTokenEndLineColumnLocation = () => {}), /full/i.test(this.config.positionTracking)) this.createTokenInstance = this.createFullToken;
				else if (/onlyStart/i.test(this.config.positionTracking)) this.createTokenInstance = this.createStartOnlyToken;
				else if (/onlyOffset/i.test(this.config.positionTracking)) this.createTokenInstance = this.createOffsetOnlyToken;
				else throw Error(`Invalid <positionTracking> config option: "${this.config.positionTracking}"`);
				this.hasCustom ? (this.addToken = this.addTokenUsingPush, this.handlePayload = this.handlePayloadWithCustom) : (this.addToken = this.addTokenUsingMemberAccess, this.handlePayload = this.handlePayloadNoCustom);
			}), this.TRACE_INIT("Failed Optimization Warnings", () => {
				let e = Object.entries(this.canModeBeOptimized).reduce((e, [t, n]) => (n === !1 && e.push(t), e), []);
				if (c.ensureOptimizations && e.length > 0) throw Error(`Lexer Modes: < ${e.join(", ")} > cannot be optimized.\n	 Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode.
	 Or inspect the console log for details on how to resolve these issues.`);
			}), this.TRACE_INIT("clearRegExpParserCache", () => {
				r();
			}), this.TRACE_INIT("toFastProperties", () => {
				n(this);
			});
		});
	}
	tokenize(e, t = this.defaultMode) {
		if (this.lexerDefinitionErrors.length > 0) {
			let e = this.lexerDefinitionErrors.map((e) => e.message).join("-----------------------\n");
			throw Error("Unable to Tokenize because Errors detected in definition of Lexer:\n" + e);
		}
		return this.tokenizeInternal(e, t);
	}
	tokenizeInternal(e, t) {
		let n, r, i, a, o, l, u, d, f, p, m, h, g, _, v, y = e, b = y.length, x = 0, S = 0, C = this.hasCustom ? 0 : Math.floor(e.length / 10), w = Array(C), T = [], E = this.trackStartLines ? 1 : void 0, D = this.trackStartLines ? 1 : void 0, O = c(this.emptyGroups), k = this.trackStartLines, A = this.config.lineTerminatorsPattern, j = 0, M = [], N = [], P = [], F = [];
		Object.freeze(F);
		let I = !1, L = (e) => {
			if (P.length === 1 && e.tokenType.PUSH_MODE === void 0) {
				let t = this.config.errorMessageProvider.buildUnableToPopLexerModeMessage(e);
				T.push({
					offset: e.startOffset,
					line: e.startLine,
					column: e.startColumn,
					length: e.image.length,
					message: t
				});
			} else {
				P.pop();
				let e = P.at(-1);
				M = this.patternIdxToConfig[e], N = this.charCodeToPatternIdxToConfig[e], j = M.length;
				let t = this.canModeBeOptimized[e] && this.config.safeMode === !1;
				I = !!(N && t);
			}
		};
		function R(e) {
			P.push(e), N = this.charCodeToPatternIdxToConfig[e], M = this.patternIdxToConfig[e], j = M.length, j = M.length;
			let t = this.canModeBeOptimized[e] && this.config.safeMode === !1;
			I = !!(N && t);
		}
		R.call(this, t);
		let z, B = this.config.recoveryEnabled;
		for (; x < b;) {
			l = null, f = -1;
			let t = y.charCodeAt(x), c;
			if (I) {
				let e = s(t), n = N[e];
				c = n === void 0 ? F : n;
			} else c = M;
			let C = c.length;
			for (n = 0; n < C; n++) {
				z = c[n];
				let r = z.pattern;
				u = null;
				let s = z.short;
				if (s === !1 ? z.isCustom === !0 ? (v = r.exec(y, x, w, O), v === null ? l = null : (l = v[0], f = l.length, v.payload !== void 0 && (u = v.payload))) : (r.lastIndex = x, f = this.matchLength(r, e, x)) : t === s && (f = 1, l = r), f !== -1) {
					if (o = z.longerAlt, o !== void 0) {
						l = e.substring(x, x + f);
						let t = o.length;
						for (i = 0; i < t; i++) {
							let t = M[o[i]], n = t.pattern;
							if (d = null, t.isCustom === !0 ? (v = n.exec(y, x, w, O), v === null ? a = null : (a = v[0], v.payload !== void 0 && (d = v.payload))) : (n.lastIndex = x, a = this.match(n, e, x)), a && a.length > l.length) {
								l = a, f = a.length, u = d, z = t;
								break;
							}
						}
					}
					break;
				}
			}
			if (f !== -1) {
				if (p = z.group, p !== void 0 && (l = l === null ? e.substring(x, x + f) : l, m = z.tokenTypeIdx, h = this.createTokenInstance(l, x, m, z.tokenType, E, D, f), this.handlePayload(h, u), p === !1 ? S = this.addToken(w, S, h) : O[p].push(h)), k === !0 && z.canLineTerminator === !0) {
					let t = 0, n, r;
					A.lastIndex = 0;
					do
						l = l === null ? e.substring(x, x + f) : l, n = A.test(l), n === !0 && (r = A.lastIndex - 1, t++);
					while (n === !0);
					t === 0 ? D = this.computeNewColumn(D, f) : (E += t, D = f - r, this.updateTokenEndLineColumnLocation(h, p, r, t, E, D, f));
				} else D = this.computeNewColumn(D, f);
				x += f, this.handleModes(z, L, R, h);
			} else {
				let t = x, n = E, i = D, a = B === !1;
				for (; a === !1 && x < b;) for (x++, r = 0; r < j; r++) {
					let t = M[r], n = t.pattern, i = t.short;
					if (i === !1 ? t.isCustom === !0 ? a = n.exec(y, x, w, O) !== null : (n.lastIndex = x, a = n.exec(e) !== null) : y.charCodeAt(x) === i && (a = !0), a === !0) break;
				}
				if (g = x - t, D = this.computeNewColumn(D, g), _ = this.config.errorMessageProvider.buildUnexpectedCharactersMessage(y, t, g, n, i, P.at(-1)), T.push({
					offset: t,
					line: n,
					column: i,
					length: g,
					message: _
				}), B === !1) break;
			}
		}
		return this.hasCustom || (w.length = S), {
			tokens: w,
			groups: O,
			errors: T
		};
	}
	handleModes(e, t, n, r) {
		if (e.pop === !0) {
			let i = e.push;
			t(r), i !== void 0 && n.call(this, i);
		} else e.push !== void 0 && n.call(this, e.push);
	}
	updateTokenEndLineColumnLocation(e, t, n, r, i, a, o) {
		let s, c;
		t !== void 0 && (s = n === o - 1, c = s ? -1 : 0, r === 1 && s === !0 || (e.endLine = i + c, e.endColumn = a - 1 + -c));
	}
	computeNewColumn(e, t) {
		return e + t;
	}
	createOffsetOnlyToken(e, t, n, r) {
		return {
			image: e,
			startOffset: t,
			tokenTypeIdx: n,
			tokenType: r
		};
	}
	createStartOnlyToken(e, t, n, r, i, a) {
		return {
			image: e,
			startOffset: t,
			startLine: i,
			startColumn: a,
			tokenTypeIdx: n,
			tokenType: r
		};
	}
	createFullToken(e, t, n, r, i, a, o) {
		return {
			image: e,
			startOffset: t,
			endOffset: t + o - 1,
			startLine: i,
			endLine: i,
			startColumn: a,
			endColumn: a + o - 1,
			tokenTypeIdx: n,
			tokenType: r
		};
	}
	addTokenUsingPush(e, t, n) {
		return e.push(n), t;
	}
	addTokenUsingMemberAccess(e, t, n) {
		return e[t] = n, t++, t;
	}
	handlePayloadNoCustom(e, t) {}
	handlePayloadWithCustom(e, t) {
		t !== null && (e.payload = t);
	}
	match(e, t, n) {
		return e.test(t) === !0 ? t.substring(n, e.lastIndex) : null;
	}
	matchLength(e, t, n) {
		return e.test(t) === !0 ? e.lastIndex - n : -1;
	}
};
g.SKIPPED = "This marks a skipped Token pattern, this means each token identified by it will be consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.", g.NA = /NOT_APPLICABLE/;
//#endregion
export { g as Lexer, m as LexerDefinitionErrorType };
