import { LineTerminatorOptimizedTester as lt, DEFAULT_MODE as ht, performRuntimeChecks as ct, performWarningRuntimeChecks as dt, SUPPORT_STICKY as ft, cloneEmptyGroups as ut, charCodeToOptimizedIndex as mt, validatePatterns as Tt, analyzeTokenTypes as It } from "./lexer.js";
import { PRINT_WARNING as gt } from "../../../../../../@chevrotain_utils@11.0.3/node_modules/@chevrotain/utils/lib/src/print.js";
import { timer as _t } from "../../../../../../@chevrotain_utils@11.0.3/node_modules/@chevrotain/utils/lib/src/timer.js";
import { toFastProperties as Et } from "../../../../../../@chevrotain_utils@11.0.3/node_modules/@chevrotain/utils/lib/src/to-fast-properties.js";
import { augmentTokenTypes as pt } from "./tokens.js";
import { defaultLexerErrorProvider as Ct } from "./lexer_errors_public.js";
import { clearRegExpParserCache as Ot } from "./reg_exp_parser.js";
import Z from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/assign.js";
import Nt from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isArray.js";
import tt from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/clone.js";
import v from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/forEach.js";
import Pt from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/keys.js";
import y from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isEmpty.js";
import et from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/map.js";
import st from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/identity.js";
import X from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/noop.js";
import At from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/reduce.js";
import Mt from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/last.js";
import Rt from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/reject.js";
import kt from "../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isUndefined.js";
var nt;
(function(s) {
  s[s.MISSING_PATTERN = 0] = "MISSING_PATTERN", s[s.INVALID_PATTERN = 1] = "INVALID_PATTERN", s[s.EOI_ANCHOR_FOUND = 2] = "EOI_ANCHOR_FOUND", s[s.UNSUPPORTED_FLAGS_FOUND = 3] = "UNSUPPORTED_FLAGS_FOUND", s[s.DUPLICATE_PATTERNS_FOUND = 4] = "DUPLICATE_PATTERNS_FOUND", s[s.INVALID_GROUP_TYPE_FOUND = 5] = "INVALID_GROUP_TYPE_FOUND", s[s.PUSH_MODE_DOES_NOT_EXIST = 6] = "PUSH_MODE_DOES_NOT_EXIST", s[s.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE = 7] = "MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE", s[s.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY = 8] = "MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY", s[s.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST = 9] = "MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST", s[s.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED = 10] = "LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED", s[s.SOI_ANCHOR_FOUND = 11] = "SOI_ANCHOR_FOUND", s[s.EMPTY_MATCH_PATTERN = 12] = "EMPTY_MATCH_PATTERN", s[s.NO_LINE_BREAKS_FLAGS = 13] = "NO_LINE_BREAKS_FLAGS", s[s.UNREACHABLE_PATTERN = 14] = "UNREACHABLE_PATTERN", s[s.IDENTIFY_TERMINATOR = 15] = "IDENTIFY_TERMINATOR", s[s.CUSTOM_LINE_BREAK = 16] = "CUSTOM_LINE_BREAK", s[s.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE = 17] = "MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE";
})(nt || (nt = {}));
const b = {
  deferDefinitionErrorsHandling: !1,
  positionTracking: "full",
  lineTerminatorsPattern: /\n|\r\n?/g,
  lineTerminatorCharacters: [`
`, "\r"],
  ensureOptimizations: !1,
  safeMode: !1,
  errorMessageProvider: Ct,
  traceInitPerf: !1,
  skipValidations: !1,
  recoveryEnabled: !0
};
Object.freeze(b);
class it {
  constructor(t, e = b) {
    if (this.lexerDefinition = t, 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 = (n, l) => {
      if (this.traceInitPerf === !0) {
        this.traceInitIndent++;
        const h = new Array(this.traceInitIndent + 1).join("	");
        this.traceInitIndent < this.traceInitMaxIdent && console.log(`${h}--> <${n}>`);
        const { time: a, value: i } = _t(l), r = a > 10 ? console.warn : console.log;
        return this.traceInitIndent < this.traceInitMaxIdent && r(`${h}<-- <${n}> time: ${a}ms`), this.traceInitIndent--, i;
      } else
        return l();
    }, typeof e == "boolean")
      throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object.
a boolean 2nd argument is no longer supported`);
    this.config = Z({}, b, e);
    const o = this.config.traceInitPerf;
    o === !0 ? (this.traceInitMaxIdent = 1 / 0, this.traceInitPerf = !0) : typeof o == "number" && (this.traceInitMaxIdent = o, this.traceInitPerf = !0), this.traceInitIndent = -1, this.TRACE_INIT("Lexer Constructor", () => {
      let n, l = !0;
      this.TRACE_INIT("Lexer Config handling", () => {
        if (this.config.lineTerminatorsPattern === b.lineTerminatorsPattern)
          this.config.lineTerminatorsPattern = lt;
        else if (this.config.lineTerminatorCharacters === b.lineTerminatorCharacters)
          throw Error(`Error: Missing <lineTerminatorCharacters> property on the Lexer config.
	For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);
        if (e.safeMode && e.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), Nt(t) ? n = {
          modes: { defaultMode: tt(t) },
          defaultMode: ht
        } : (l = !1, n = tt(t));
      }), this.config.skipValidations === !1 && (this.TRACE_INIT("performRuntimeChecks", () => {
        this.lexerDefinitionErrors = this.lexerDefinitionErrors.concat(ct(n, this.trackStartLines, this.config.lineTerminatorCharacters));
      }), this.TRACE_INIT("performWarningRuntimeChecks", () => {
        this.lexerDefinitionWarning = this.lexerDefinitionWarning.concat(dt(n, this.trackStartLines, this.config.lineTerminatorCharacters));
      })), n.modes = n.modes ? n.modes : {}, v(n.modes, (a, i) => {
        n.modes[i] = Rt(a, (r) => kt(r));
      });
      const h = Pt(n.modes);
      if (v(n.modes, (a, i) => {
        this.TRACE_INIT(`Mode: <${i}> processing`, () => {
          if (this.modes.push(i), this.config.skipValidations === !1 && this.TRACE_INIT("validatePatterns", () => {
            this.lexerDefinitionErrors = this.lexerDefinitionErrors.concat(Tt(a, h));
          }), y(this.lexerDefinitionErrors)) {
            pt(a);
            let r;
            this.TRACE_INIT("analyzeTokenTypes", () => {
              r = It(a, {
                lineTerminatorCharacters: this.config.lineTerminatorCharacters,
                positionTracking: e.positionTracking,
                ensureOptimizations: e.ensureOptimizations,
                safeMode: e.safeMode,
                tracer: this.TRACE_INIT
              });
            }), this.patternIdxToConfig[i] = r.patternIdxToConfig, this.charCodeToPatternIdxToConfig[i] = r.charCodeToPatternIdxToConfig, this.emptyGroups = Z({}, this.emptyGroups, r.emptyGroups), this.hasCustom = r.hasCustom || this.hasCustom, this.canModeBeOptimized[i] = r.canBeOptimized;
          }
        });
      }), this.defaultMode = n.defaultMode, !y(this.lexerDefinitionErrors) && !this.config.deferDefinitionErrorsHandling) {
        const i = et(this.lexerDefinitionErrors, (r) => r.message).join(`-----------------------
`);
        throw new Error(`Errors detected in definition of Lexer:
` + i);
      }
      v(this.lexerDefinitionWarning, (a) => {
        gt(a.message);
      }), this.TRACE_INIT("Choosing sub-methods implementations", () => {
        if (ft ? (this.chopInput = st, this.match = this.matchWithTest) : (this.updateLastIndex = X, this.match = this.matchWithExec), l && (this.handleModes = X), this.trackStartLines === !1 && (this.computeNewColumn = st), this.trackEndLines === !1 && (this.updateTokenEndLineColumnLocation = X), /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", () => {
        const a = At(this.canModeBeOptimized, (i, r, R) => (r === !1 && i.push(R), i), []);
        if (e.ensureOptimizations && !y(a))
          throw Error(`Lexer Modes: < ${a.join(", ")} > cannot be optimized.
	 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", () => {
        Ot();
      }), this.TRACE_INIT("toFastProperties", () => {
        Et(this);
      });
    });
  }
  tokenize(t, e = this.defaultMode) {
    if (!y(this.lexerDefinitionErrors)) {
      const n = et(this.lexerDefinitionErrors, (l) => l.message).join(`-----------------------
`);
      throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer:
` + n);
    }
    return this.tokenizeInternal(t, e);
  }
  // There is quite a bit of duplication between this and "tokenizeInternalLazy"
  // This is intentional due to performance considerations.
  // this method also used quite a bit of `!` none null assertions because it is too optimized
  // for `tsc` to always understand it is "safe"
  tokenizeInternal(t, e) {
    let o, n, l, h, a, i, r, R, C, k, B, P, F, V, T;
    const O = t, j = O.length;
    let c = 0, w = 0;
    const ot = this.hasCustom ? 0 : Math.floor(t.length / 10), A = new Array(ot), G = [];
    let L = this.trackStartLines ? 1 : void 0, _ = this.trackStartLines ? 1 : void 0;
    const U = ut(this.emptyGroups), at = this.trackStartLines, H = this.config.lineTerminatorsPattern;
    let z = 0, E = [], S = [];
    const x = [], Y = [];
    Object.freeze(Y);
    let D;
    function $() {
      return E;
    }
    function K(d) {
      const u = mt(d), M = S[u];
      return M === void 0 ? Y : M;
    }
    const rt = (d) => {
      if (x.length === 1 && // if we have both a POP_MODE and a PUSH_MODE this is in-fact a "transition"
      // So no error should occur.
      d.tokenType.PUSH_MODE === void 0) {
        const u = this.config.errorMessageProvider.buildUnableToPopLexerModeMessage(d);
        G.push({
          offset: d.startOffset,
          line: d.startLine,
          column: d.startColumn,
          length: d.image.length,
          message: u
        });
      } else {
        x.pop();
        const u = Mt(x);
        E = this.patternIdxToConfig[u], S = this.charCodeToPatternIdxToConfig[u], z = E.length;
        const M = this.canModeBeOptimized[u] && this.config.safeMode === !1;
        S && M ? D = K : D = $;
      }
    };
    function q(d) {
      x.push(d), S = this.charCodeToPatternIdxToConfig[d], E = this.patternIdxToConfig[d], z = E.length, z = E.length;
      const u = this.canModeBeOptimized[d] && this.config.safeMode === !1;
      S && u ? D = K : D = $;
    }
    q.call(this, e);
    let m;
    const J = this.config.recoveryEnabled;
    for (; c < j; ) {
      i = null;
      const d = O.charCodeAt(c), u = D(d), M = u.length;
      for (o = 0; o < M; o++) {
        m = u[o];
        const f = m.pattern;
        r = null;
        const I = m.short;
        if (I !== !1 ? d === I && (i = f) : m.isCustom === !0 ? (T = f.exec(O, c, A, U), T !== null ? (i = T[0], T.payload !== void 0 && (r = T.payload)) : i = null) : (this.updateLastIndex(f, c), i = this.match(f, t, c)), i !== null) {
          if (a = m.longerAlt, a !== void 0) {
            const p = a.length;
            for (l = 0; l < p; l++) {
              const g = E[a[l]], N = g.pattern;
              if (R = null, g.isCustom === !0 ? (T = N.exec(O, c, A, U), T !== null ? (h = T[0], T.payload !== void 0 && (R = T.payload)) : h = null) : (this.updateLastIndex(N, c), h = this.match(N, t, c)), h && h.length > i.length) {
                i = h, r = R, m = g;
                break;
              }
            }
          }
          break;
        }
      }
      if (i !== null) {
        if (C = i.length, k = m.group, k !== void 0 && (B = m.tokenTypeIdx, P = this.createTokenInstance(i, c, B, m.tokenType, L, _, C), this.handlePayload(P, r), k === !1 ? w = this.addToken(A, w, P) : U[k].push(P)), t = this.chopInput(t, C), c = c + C, _ = this.computeNewColumn(_, C), at === !0 && m.canLineTerminator === !0) {
          let f = 0, I, p;
          H.lastIndex = 0;
          do
            I = H.test(i), I === !0 && (p = H.lastIndex - 1, f++);
          while (I === !0);
          f !== 0 && (L = L + f, _ = C - p, this.updateTokenEndLineColumnLocation(P, k, p, f, L, _, C));
        }
        this.handleModes(m, rt, q, P);
      } else {
        const f = c, I = L, p = _;
        let g = J === !1;
        for (; g === !1 && c < j; )
          for (t = this.chopInput(t, 1), c++, n = 0; n < z; n++) {
            const N = E[n], W = N.pattern, Q = N.short;
            if (Q !== !1 ? O.charCodeAt(c) === Q && (g = !0) : N.isCustom === !0 ? g = W.exec(O, c, A, U) !== null : (this.updateLastIndex(W, c), g = W.exec(t) !== null), g === !0)
              break;
          }
        if (F = c - f, _ = this.computeNewColumn(_, F), V = this.config.errorMessageProvider.buildUnexpectedCharactersMessage(O, f, F, I, p), G.push({
          offset: f,
          line: I,
          column: p,
          length: F,
          message: V
        }), J === !1)
          break;
      }
    }
    return this.hasCustom || (A.length = w), {
      tokens: A,
      groups: U,
      errors: G
    };
  }
  handleModes(t, e, o, n) {
    if (t.pop === !0) {
      const l = t.push;
      e(n), l !== void 0 && o.call(this, l);
    } else t.push !== void 0 && o.call(this, t.push);
  }
  chopInput(t, e) {
    return t.substring(e);
  }
  updateLastIndex(t, e) {
    t.lastIndex = e;
  }
  // TODO: decrease this under 600 characters? inspect stripping comments option in TSC compiler
  updateTokenEndLineColumnLocation(t, e, o, n, l, h, a) {
    let i, r;
    e !== void 0 && (i = o === a - 1, r = i ? -1 : 0, n === 1 && i === !0 || (t.endLine = l + r, t.endColumn = h - 1 + -r));
  }
  computeNewColumn(t, e) {
    return t + e;
  }
  createOffsetOnlyToken(t, e, o, n) {
    return {
      image: t,
      startOffset: e,
      tokenTypeIdx: o,
      tokenType: n
    };
  }
  createStartOnlyToken(t, e, o, n, l, h) {
    return {
      image: t,
      startOffset: e,
      startLine: l,
      startColumn: h,
      tokenTypeIdx: o,
      tokenType: n
    };
  }
  createFullToken(t, e, o, n, l, h, a) {
    return {
      image: t,
      startOffset: e,
      endOffset: e + a - 1,
      startLine: l,
      endLine: l,
      startColumn: h,
      endColumn: h + a - 1,
      tokenTypeIdx: o,
      tokenType: n
    };
  }
  addTokenUsingPush(t, e, o) {
    return t.push(o), e;
  }
  addTokenUsingMemberAccess(t, e, o) {
    return t[e] = o, e++, e;
  }
  handlePayloadNoCustom(t, e) {
  }
  handlePayloadWithCustom(t, e) {
    e !== null && (t.payload = e);
  }
  matchWithTest(t, e, o) {
    return t.test(e) === !0 ? e.substring(o, t.lastIndex) : null;
  }
  matchWithExec(t, e) {
    const o = t.exec(e);
    return o !== null ? o[0] : null;
  }
}
it.SKIPPED = "This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.";
it.NA = /NOT_APPLICABLE/;
export {
  it as Lexer,
  nt as LexerDefinitionErrorType
};
