import { BITS_FOR_METHOD_TYPE as v, BITS_FOR_OCCURRENCE_IDX as K, OPTION_IDX as U, AT_LEAST_ONE_IDX as S, AT_LEAST_ONE_SEP_IDX as m, MANY_IDX as R, MANY_SEP_IDX as T, OR_IDX as x } from "../../grammar/keys.js";
import { isRecognitionException as f, NotAllInputParsedException as M, MismatchedTokenException as w } from "../../exceptions_public.js";
import { PROD_TYPE as p } from "../../grammar/lookahead.js";
import { NextTerminalAfterAtLeastOneWalker as P, NextTerminalAfterAtLeastOneSepWalker as A, NextTerminalAfterManyWalker as G, NextTerminalAfterManySepWalker as I } from "../../grammar/interpreter.js";
import { DEFAULT_RULE_CONFIG as L } from "../parser.js";
import { IN_RULE_RECOVERY_EXCEPTION as B } from "./recoverable.js";
import { EOF as C } from "../../../scan/tokens_public.js";
import { tokenStructuredMatcherNoCategories as g, isTokenType as b, tokenStructuredMatcher as O, augmentTokenTypes as D } from "../../../scan/tokens.js";
import h from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/has.js";
import E from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isArray.js";
import y from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isEmpty.js";
import F from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/reduce.js";
import _ from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/every.js";
import d from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/flatten.js";
import c from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/values.js";
import X from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/uniq.js";
import W from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isObject.js";
import k from "../../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/clone.js";
class ht {
  initRecognizerEngine(t, e) {
    if (this.className = this.constructor.name, this.shortRuleNameToFull = {}, this.fullRuleNameToShort = {}, this.ruleShortNameIdx = 256, this.tokenMatcher = g, this.subruleIdx = 0, this.definedRulesNames = [], this.tokensMap = {}, this.isBackTrackingStack = [], this.RULE_STACK = [], this.RULE_OCCURRENCE_STACK = [], this.gastProductionsCache = {}, h(e, "serializedGrammar"))
      throw Error(`The Parser's configuration can no longer contain a <serializedGrammar> property.
	See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0
	For Further details.`);
    if (E(t)) {
      if (y(t))
        throw Error(`A Token Vocabulary cannot be empty.
	Note that the first argument for the parser constructor
	is no longer a Token vector (since v4.0).`);
      if (typeof t[0].startOffset == "number")
        throw Error(`The Parser constructor no longer accepts a token vector as the first argument.
	See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0
	For Further details.`);
    }
    if (E(t))
      this.tokensMap = F(t, (i, n) => (i[n.name] = n, i), {});
    else if (h(t, "modes") && _(d(c(t.modes)), b)) {
      const i = d(c(t.modes)), n = X(i);
      this.tokensMap = F(n, (a, o) => (a[o.name] = o, a), {});
    } else if (W(t))
      this.tokensMap = k(t);
    else
      throw new Error("<tokensDictionary> argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");
    this.tokensMap.EOF = C;
    const r = h(t, "modes") ? d(c(t.modes)) : c(t), s = _(r, (i) => y(i.categoryMatches));
    this.tokenMatcher = s ? g : O, D(c(this.tokensMap));
  }
  defineRule(t, e, r) {
    if (this.selfAnalysisDone)
      throw Error(`Grammar rule <${t}> may not be defined after the 'performSelfAnalysis' method has been called'
Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);
    const s = h(r, "resyncEnabled") ? r.resyncEnabled : L.resyncEnabled, i = h(r, "recoveryValueFunc") ? r.recoveryValueFunc : L.recoveryValueFunc, n = this.ruleShortNameIdx << v + K;
    this.ruleShortNameIdx++, this.shortRuleNameToFull[n] = t, this.fullRuleNameToShort[t] = n;
    let a;
    return this.outputCst === !0 ? a = function(...u) {
      try {
        this.ruleInvocationStateUpdate(n, t, this.subruleIdx), e.apply(this, u);
        const l = this.CST_STACK[this.CST_STACK.length - 1];
        return this.cstPostRule(l), l;
      } catch (l) {
        return this.invokeRuleCatch(l, s, i);
      } finally {
        this.ruleFinallyStateUpdate();
      }
    } : a = function(...u) {
      try {
        return this.ruleInvocationStateUpdate(n, t, this.subruleIdx), e.apply(this, u);
      } catch (l) {
        return this.invokeRuleCatch(l, s, i);
      } finally {
        this.ruleFinallyStateUpdate();
      }
    }, Object.assign(a, { ruleName: t, originalGrammarAction: e });
  }
  invokeRuleCatch(t, e, r) {
    const s = this.RULE_STACK.length === 1, i = e && !this.isBackTracking() && this.recoveryEnabled;
    if (f(t)) {
      const n = t;
      if (i) {
        const a = this.findReSyncTokenType();
        if (this.isInCurrentRuleReSyncSet(a))
          if (n.resyncedTokens = this.reSyncTo(a), this.outputCst) {
            const o = this.CST_STACK[this.CST_STACK.length - 1];
            return o.recoveredNode = !0, o;
          } else
            return r(t);
        else {
          if (this.outputCst) {
            const o = this.CST_STACK[this.CST_STACK.length - 1];
            o.recoveredNode = !0, n.partialCstResult = o;
          }
          throw n;
        }
      } else {
        if (s)
          return this.moveToTerminatedState(), r(t);
        throw n;
      }
    } else
      throw t;
  }
  // Implementation of parsing DSL
  optionInternal(t, e) {
    const r = this.getKeyForAutomaticLookahead(U, e);
    return this.optionInternalLogic(t, e, r);
  }
  optionInternalLogic(t, e, r) {
    let s = this.getLaFuncFromCache(r), i;
    if (typeof t != "function") {
      i = t.DEF;
      const n = t.GATE;
      if (n !== void 0) {
        const a = s;
        s = () => n.call(this) && a.call(this);
      }
    } else
      i = t;
    if (s.call(this) === !0)
      return i.call(this);
  }
  atLeastOneInternal(t, e) {
    const r = this.getKeyForAutomaticLookahead(S, t);
    return this.atLeastOneInternalLogic(t, e, r);
  }
  atLeastOneInternalLogic(t, e, r) {
    let s = this.getLaFuncFromCache(r), i;
    if (typeof e != "function") {
      i = e.DEF;
      const n = e.GATE;
      if (n !== void 0) {
        const a = s;
        s = () => n.call(this) && a.call(this);
      }
    } else
      i = e;
    if (s.call(this) === !0) {
      let n = this.doSingleRepetition(i);
      for (; s.call(this) === !0 && n === !0; )
        n = this.doSingleRepetition(i);
    } else
      throw this.raiseEarlyExitException(t, p.REPETITION_MANDATORY, e.ERR_MSG);
    this.attemptInRepetitionRecovery(this.atLeastOneInternal, [t, e], s, S, t, P);
  }
  atLeastOneSepFirstInternal(t, e) {
    const r = this.getKeyForAutomaticLookahead(m, t);
    this.atLeastOneSepFirstInternalLogic(t, e, r);
  }
  atLeastOneSepFirstInternalLogic(t, e, r) {
    const s = e.DEF, i = e.SEP;
    if (this.getLaFuncFromCache(r).call(this) === !0) {
      s.call(this);
      const a = () => this.tokenMatcher(this.LA(1), i);
      for (; this.tokenMatcher(this.LA(1), i) === !0; )
        this.CONSUME(i), s.call(this);
      this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal, [
        t,
        i,
        a,
        s,
        A
      ], a, m, t, A);
    } else
      throw this.raiseEarlyExitException(t, p.REPETITION_MANDATORY_WITH_SEPARATOR, e.ERR_MSG);
  }
  manyInternal(t, e) {
    const r = this.getKeyForAutomaticLookahead(R, t);
    return this.manyInternalLogic(t, e, r);
  }
  manyInternalLogic(t, e, r) {
    let s = this.getLaFuncFromCache(r), i;
    if (typeof e != "function") {
      i = e.DEF;
      const a = e.GATE;
      if (a !== void 0) {
        const o = s;
        s = () => a.call(this) && o.call(this);
      }
    } else
      i = e;
    let n = !0;
    for (; s.call(this) === !0 && n === !0; )
      n = this.doSingleRepetition(i);
    this.attemptInRepetitionRecovery(
      this.manyInternal,
      [t, e],
      s,
      R,
      t,
      G,
      // The notStuck parameter is only relevant when "attemptInRepetitionRecovery"
      // is invoked from manyInternal, in the MANY_SEP case and AT_LEAST_ONE[_SEP]
      // An infinite loop cannot occur as:
      // - Either the lookahead is guaranteed to consume something (Single Token Separator)
      // - AT_LEAST_ONE by definition is guaranteed to consume something (or error out).
      n
    );
  }
  manySepFirstInternal(t, e) {
    const r = this.getKeyForAutomaticLookahead(T, t);
    this.manySepFirstInternalLogic(t, e, r);
  }
  manySepFirstInternalLogic(t, e, r) {
    const s = e.DEF, i = e.SEP;
    if (this.getLaFuncFromCache(r).call(this) === !0) {
      s.call(this);
      const a = () => this.tokenMatcher(this.LA(1), i);
      for (; this.tokenMatcher(this.LA(1), i) === !0; )
        this.CONSUME(i), s.call(this);
      this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal, [
        t,
        i,
        a,
        s,
        I
      ], a, T, t, I);
    }
  }
  repetitionSepSecondInternal(t, e, r, s, i) {
    for (; r(); )
      this.CONSUME(e), s.call(this);
    this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal, [
      t,
      e,
      r,
      s,
      i
    ], r, m, t, i);
  }
  doSingleRepetition(t) {
    const e = this.getLexerPosition();
    return t.call(this), this.getLexerPosition() > e;
  }
  orInternal(t, e) {
    const r = this.getKeyForAutomaticLookahead(x, e), s = E(t) ? t : t.DEF, n = this.getLaFuncFromCache(r).call(this, s);
    if (n !== void 0)
      return s[n].ALT.call(this);
    this.raiseNoAltException(e, t.ERR_MSG);
  }
  ruleFinallyStateUpdate() {
    if (this.RULE_STACK.pop(), this.RULE_OCCURRENCE_STACK.pop(), this.cstFinallyStateUpdate(), this.RULE_STACK.length === 0 && this.isAtEndOfInput() === !1) {
      const t = this.LA(1), e = this.errorMessageProvider.buildNotAllInputParsedMessage({
        firstRedundant: t,
        ruleName: this.getCurrRuleFullName()
      });
      this.SAVE_ERROR(new M(e, t));
    }
  }
  subruleInternal(t, e, r) {
    let s;
    try {
      const i = r !== void 0 ? r.ARGS : void 0;
      return this.subruleIdx = e, s = t.apply(this, i), this.cstPostNonTerminal(s, r !== void 0 && r.LABEL !== void 0 ? r.LABEL : t.ruleName), s;
    } catch (i) {
      throw this.subruleInternalError(i, r, t.ruleName);
    }
  }
  subruleInternalError(t, e, r) {
    throw f(t) && t.partialCstResult !== void 0 && (this.cstPostNonTerminal(t.partialCstResult, e !== void 0 && e.LABEL !== void 0 ? e.LABEL : r), delete t.partialCstResult), t;
  }
  consumeInternal(t, e, r) {
    let s;
    try {
      const i = this.LA(1);
      this.tokenMatcher(i, t) === !0 ? (this.consumeToken(), s = i) : this.consumeInternalError(t, i, r);
    } catch (i) {
      s = this.consumeInternalRecovery(t, e, i);
    }
    return this.cstPostTerminal(r !== void 0 && r.LABEL !== void 0 ? r.LABEL : t.name, s), s;
  }
  consumeInternalError(t, e, r) {
    let s;
    const i = this.LA(0);
    throw r !== void 0 && r.ERR_MSG ? s = r.ERR_MSG : s = this.errorMessageProvider.buildMismatchTokenMessage({
      expected: t,
      actual: e,
      previous: i,
      ruleName: this.getCurrRuleFullName()
    }), this.SAVE_ERROR(new w(s, e, i));
  }
  consumeInternalRecovery(t, e, r) {
    if (this.recoveryEnabled && // TODO: more robust checking of the exception type. Perhaps Typescript extending expressions?
    r.name === "MismatchedTokenException" && !this.isBackTracking()) {
      const s = this.getFollowsForInRuleRecovery(t, e);
      try {
        return this.tryInRuleRecovery(t, s);
      } catch (i) {
        throw i.name === B ? r : i;
      }
    } else
      throw r;
  }
  saveRecogState() {
    const t = this.errors, e = k(this.RULE_STACK);
    return {
      errors: t,
      lexerState: this.exportLexerState(),
      RULE_STACK: e,
      CST_STACK: this.CST_STACK
    };
  }
  reloadRecogState(t) {
    this.errors = t.errors, this.importLexerState(t.lexerState), this.RULE_STACK = t.RULE_STACK;
  }
  ruleInvocationStateUpdate(t, e, r) {
    this.RULE_OCCURRENCE_STACK.push(r), this.RULE_STACK.push(t), this.cstInvocationStateUpdate(e);
  }
  isBackTracking() {
    return this.isBackTrackingStack.length !== 0;
  }
  getCurrRuleFullName() {
    const t = this.getLastExplicitRuleShortName();
    return this.shortRuleNameToFull[t];
  }
  shortRuleNameToFullName(t) {
    return this.shortRuleNameToFull[t];
  }
  isAtEndOfInput() {
    return this.tokenMatcher(this.LA(1), C);
  }
  reset() {
    this.resetLexerState(), this.subruleIdx = 0, this.isBackTrackingStack = [], this.errors = [], this.RULE_STACK = [], this.CST_STACK = [], this.RULE_OCCURRENCE_STACK = [];
  }
}
export {
  ht as RecognizerEngine
};
