import { EmbeddedActionsParser as w } from "../../../../../chevrotain@11.0.3/node_modules/chevrotain/lib/src/parse/parser/parser.js";
import "../../../../../chevrotain@11.0.3/node_modules/chevrotain/lib/src/scan/lexer_public.js";
import "../../../../../chevrotain@11.0.3/node_modules/chevrotain/lib/src/scan/tokens_public.js";
import "../../../../../chevrotain@11.0.3/node_modules/chevrotain/lib/src/parse/grammar/lookahead.js";
import { LLkLookaheadStrategy as b } from "../../../../../chevrotain@11.0.3/node_modules/chevrotain/lib/src/parse/grammar/llk_lookahead.js";
import { defaultParserErrorProvider as u } from "../../../../../chevrotain@11.0.3/node_modules/chevrotain/lib/src/parse/errors_public.js";
import "../../../../../chevrotain@11.0.3/node_modules/chevrotain/lib/src/parse/exceptions_public.js";
import { LLStarLookaheadStrategy as R } from "../../../../../chevrotain-allstar@0.3.1_chevrotain@11.0.3/node_modules/chevrotain-allstar/lib/all-star-lookahead.js";
import { isKeyword as m, isAssignment as S, isCrossReference as x } from "../languages/generated/ast.js";
import { isDataTypeRule as y, getExplicitRuleType as E } from "../utils/grammar-utils.js";
import { linkContentToContainer as N, assignMandatoryProperties as M, getContainerOfType as L } from "../utils/ast-utils.js";
import { CstNodeBuilder as A } from "./cst-node-builder.js";
const c = Symbol("Datatype");
function h(o) {
  return o.$type === c;
}
const f = "​", g = (o) => o.endsWith(f) ? o : o + f;
class k {
  constructor(e) {
    this._unorderedGroups = /* @__PURE__ */ new Map(), this.allRules = /* @__PURE__ */ new Map(), this.lexer = e.parser.Lexer;
    const t = this.lexer.definition, s = e.LanguageMetaData.mode === "production";
    this.wrapper = new C(t, Object.assign(Object.assign({}, e.parser.ParserConfig), { skipValidations: s, errorMessageProvider: e.parser.ParserErrorMessageProvider }));
  }
  alternatives(e, t) {
    this.wrapper.wrapOr(e, t);
  }
  optional(e, t) {
    this.wrapper.wrapOption(e, t);
  }
  many(e, t) {
    this.wrapper.wrapMany(e, t);
  }
  atLeastOne(e, t) {
    this.wrapper.wrapAtLeastOne(e, t);
  }
  getRule(e) {
    return this.allRules.get(e);
  }
  isRecording() {
    return this.wrapper.IS_RECORDING;
  }
  get unorderedGroups() {
    return this._unorderedGroups;
  }
  getRuleStack() {
    return this.wrapper.RULE_STACK;
  }
  finalize() {
    this.wrapper.wrapSelfAnalysis();
  }
}
class H extends k {
  get current() {
    return this.stack[this.stack.length - 1];
  }
  constructor(e) {
    super(e), this.nodeBuilder = new A(), this.stack = [], this.assignmentMap = /* @__PURE__ */ new Map(), this.linker = e.references.Linker, this.converter = e.parser.ValueConverter, this.astReflection = e.shared.AstReflection;
  }
  rule(e, t) {
    const s = this.computeRuleType(e), r = this.wrapper.DEFINE_RULE(g(e.name), this.startImplementation(s, t).bind(this));
    return this.allRules.set(e.name, r), e.entry && (this.mainRule = r), r;
  }
  computeRuleType(e) {
    if (!e.fragment) {
      if (y(e))
        return c;
      {
        const t = E(e);
        return t ?? e.name;
      }
    }
  }
  parse(e, t = {}) {
    this.nodeBuilder.buildRootNode(e);
    const s = this.lexerResult = this.lexer.tokenize(e);
    this.wrapper.input = s.tokens;
    const r = t.rule ? this.allRules.get(t.rule) : this.mainRule;
    if (!r)
      throw new Error(t.rule ? `No rule found with name '${t.rule}'` : "No main rule available.");
    const n = r.call(this.wrapper, {});
    return this.nodeBuilder.addHiddenNodes(s.hidden), this.unorderedGroups.clear(), this.lexerResult = void 0, {
      value: n,
      lexerErrors: s.errors,
      lexerReport: s.report,
      parserErrors: this.wrapper.errors
    };
  }
  startImplementation(e, t) {
    return (s) => {
      const r = !this.isRecording() && e !== void 0;
      if (r) {
        const i = { $type: e };
        this.stack.push(i), e === c && (i.value = "");
      }
      let n;
      try {
        n = t(s);
      } catch {
        n = void 0;
      }
      return n === void 0 && r && (n = this.construct()), n;
    };
  }
  extractHiddenTokens(e) {
    const t = this.lexerResult.hidden;
    if (!t.length)
      return [];
    const s = e.startOffset;
    for (let r = 0; r < t.length; r++)
      if (t[r].startOffset > s)
        return t.splice(0, r);
    return t.splice(0, t.length);
  }
  consume(e, t, s) {
    const r = this.wrapper.wrapConsume(e, t);
    if (!this.isRecording() && this.isValidToken(r)) {
      const n = this.extractHiddenTokens(r);
      this.nodeBuilder.addHiddenNodes(n);
      const i = this.nodeBuilder.buildLeafNode(r, s), { assignment: a, isCrossRef: d } = this.getAssignment(s), p = this.current;
      if (a) {
        const l = m(s) ? r.image : this.converter.convert(r.image, i);
        this.assign(a.operator, a.feature, l, i, d);
      } else if (h(p)) {
        let l = r.image;
        m(s) || (l = this.converter.convert(l, i).toString()), p.value += l;
      }
    }
  }
  /**
   * Most consumed parser tokens are valid. However there are two cases in which they are not valid:
   *
   * 1. They were inserted during error recovery by the parser. These tokens don't really exist and should not be further processed
   * 2. They contain invalid token ranges. This might include the special EOF token, or other tokens produced by invalid token builders.
   */
  isValidToken(e) {
    return !e.isInsertedInRecovery && !isNaN(e.startOffset) && typeof e.endOffset == "number" && !isNaN(e.endOffset);
  }
  subrule(e, t, s, r, n) {
    let i;
    !this.isRecording() && !s && (i = this.nodeBuilder.buildCompositeNode(r));
    const a = this.wrapper.wrapSubrule(e, t, n);
    !this.isRecording() && i && i.length > 0 && this.performSubruleAssignment(a, r, i);
  }
  performSubruleAssignment(e, t, s) {
    const { assignment: r, isCrossRef: n } = this.getAssignment(t);
    if (r)
      this.assign(r.operator, r.feature, e, s, n);
    else if (!r) {
      const i = this.current;
      if (h(i))
        i.value += e.toString();
      else if (typeof e == "object" && e) {
        const d = this.assignWithoutOverride(e, i);
        this.stack.pop(), this.stack.push(d);
      }
    }
  }
  action(e, t) {
    if (!this.isRecording()) {
      let s = this.current;
      if (t.feature && t.operator) {
        s = this.construct(), this.nodeBuilder.removeNode(s.$cstNode), this.nodeBuilder.buildCompositeNode(t).content.push(s.$cstNode);
        const n = { $type: e };
        this.stack.push(n), this.assign(t.operator, t.feature, s, s.$cstNode, !1);
      } else
        s.$type = e;
    }
  }
  construct() {
    if (this.isRecording())
      return;
    const e = this.current;
    return N(e), this.nodeBuilder.construct(e), this.stack.pop(), h(e) ? this.converter.convert(e.value, e.$cstNode) : (M(this.astReflection, e), e);
  }
  getAssignment(e) {
    if (!this.assignmentMap.has(e)) {
      const t = L(e, S);
      this.assignmentMap.set(e, {
        assignment: t,
        isCrossRef: t ? x(t.terminal) : !1
      });
    }
    return this.assignmentMap.get(e);
  }
  assign(e, t, s, r, n) {
    const i = this.current;
    let a;
    switch (n && typeof s == "string" ? a = this.linker.buildReference(i, t, r, s) : a = s, e) {
      case "=": {
        i[t] = a;
        break;
      }
      case "?=": {
        i[t] = !0;
        break;
      }
      case "+=":
        Array.isArray(i[t]) || (i[t] = []), i[t].push(a);
    }
  }
  assignWithoutOverride(e, t) {
    for (const [r, n] of Object.entries(t)) {
      const i = e[r];
      i === void 0 ? e[r] = n : Array.isArray(i) && Array.isArray(n) && (n.push(...i), e[r] = n);
    }
    const s = e.$cstNode;
    return s && (s.astNode = void 0, e.$cstNode = void 0), e;
  }
  get definitionErrors() {
    return this.wrapper.definitionErrors;
  }
}
class I {
  buildMismatchTokenMessage(e) {
    return u.buildMismatchTokenMessage(e);
  }
  buildNotAllInputParsedMessage(e) {
    return u.buildNotAllInputParsedMessage(e);
  }
  buildNoViableAltMessage(e) {
    return u.buildNoViableAltMessage(e);
  }
  buildEarlyExitMessage(e) {
    return u.buildEarlyExitMessage(e);
  }
}
class O extends I {
  buildMismatchTokenMessage({ expected: e, actual: t }) {
    return `Expecting ${e.LABEL ? "`" + e.LABEL + "`" : e.name.endsWith(":KW") ? `keyword '${e.name.substring(0, e.name.length - 3)}'` : `token of type '${e.name}'`} but found \`${t.image}\`.`;
  }
  buildNotAllInputParsedMessage({ firstRedundant: e }) {
    return `Expecting end of file but found \`${e.image}\`.`;
  }
}
class F extends k {
  constructor() {
    super(...arguments), this.tokens = [], this.elementStack = [], this.lastElementStack = [], this.nextTokenIndex = 0, this.stackSize = 0;
  }
  action() {
  }
  construct() {
  }
  parse(e) {
    this.resetState();
    const t = this.lexer.tokenize(e, { mode: "partial" });
    return this.tokens = t.tokens, this.wrapper.input = [...this.tokens], this.mainRule.call(this.wrapper, {}), this.unorderedGroups.clear(), {
      tokens: this.tokens,
      elementStack: [...this.lastElementStack],
      tokenIndex: this.nextTokenIndex
    };
  }
  rule(e, t) {
    const s = this.wrapper.DEFINE_RULE(g(e.name), this.startImplementation(t).bind(this));
    return this.allRules.set(e.name, s), e.entry && (this.mainRule = s), s;
  }
  resetState() {
    this.elementStack = [], this.lastElementStack = [], this.nextTokenIndex = 0, this.stackSize = 0;
  }
  startImplementation(e) {
    return (t) => {
      const s = this.keepStackSize();
      try {
        e(t);
      } finally {
        this.resetStackSize(s);
      }
    };
  }
  removeUnexpectedElements() {
    this.elementStack.splice(this.stackSize);
  }
  keepStackSize() {
    const e = this.elementStack.length;
    return this.stackSize = e, e;
  }
  resetStackSize(e) {
    this.removeUnexpectedElements(), this.stackSize = e;
  }
  consume(e, t, s) {
    this.wrapper.wrapConsume(e, t), this.isRecording() || (this.lastElementStack = [...this.elementStack, s], this.nextTokenIndex = this.currIdx + 1);
  }
  subrule(e, t, s, r, n) {
    this.before(r), this.wrapper.wrapSubrule(e, t, n), this.after(r);
  }
  before(e) {
    this.isRecording() || this.elementStack.push(e);
  }
  after(e) {
    if (!this.isRecording()) {
      const t = this.elementStack.lastIndexOf(e);
      t >= 0 && this.elementStack.splice(t);
    }
  }
  get currIdx() {
    return this.wrapper.currIdx;
  }
}
const v = {
  recoveryEnabled: !0,
  nodeLocationTracking: "full",
  skipValidations: !0,
  errorMessageProvider: new O()
};
class C extends w {
  constructor(e, t) {
    const s = t && "maxLookahead" in t;
    super(e, Object.assign(Object.assign(Object.assign({}, v), { lookaheadStrategy: s ? new b({ maxLookahead: t.maxLookahead }) : new R({
      // If validations are skipped, don't log the lookahead warnings
      logging: t.skipValidations ? () => {
      } : void 0
    }) }), t));
  }
  get IS_RECORDING() {
    return this.RECORDING_PHASE;
  }
  DEFINE_RULE(e, t) {
    return this.RULE(e, t);
  }
  wrapSelfAnalysis() {
    this.performSelfAnalysis();
  }
  wrapConsume(e, t) {
    return this.consume(e, t);
  }
  wrapSubrule(e, t, s) {
    return this.subrule(e, t, {
      ARGS: [s]
    });
  }
  wrapOr(e, t) {
    this.or(e, t);
  }
  wrapOption(e, t) {
    this.option(e, t);
  }
  wrapMany(e, t) {
    this.many(e, t);
  }
  wrapAtLeastOne(e, t) {
    this.atLeastOne(e, t);
  }
}
export {
  k as AbstractLangiumParser,
  I as AbstractParserErrorMessageProvider,
  c as DatatypeSymbol,
  F as LangiumCompletionParser,
  H as LangiumParser,
  O as LangiumParserErrorMessageProvider
};
