var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/atn/LexerActionExecutor.ts
var LexerActionExecutor_exports = {};
__export(LexerActionExecutor_exports, {
  LexerActionExecutor: () => LexerActionExecutor
});
module.exports = __toCommonJS(LexerActionExecutor_exports);

// src/utils/MurmurHash.ts
var c1 = 3432918353;
var c2 = 461845907;
var r1 = 15;
var r2 = 13;
var m = 5;
var n = 3864292196;
var MurmurHash = class _MurmurHash {
  static {
    __name(this, "MurmurHash");
  }
  static defaultSeed = 701;
  constructor() {
  }
  /**
   * Initialize the hash using the specified {@code seed}.
   *
   * @param seed the seed
   *
   * @returns the intermediate hash value
   */
  static initialize(seed = _MurmurHash.defaultSeed) {
    return seed;
  }
  static updateFromComparable(hash, value) {
    return this.update(hash, value?.hashCode() ?? 0);
  }
  /**
   * Update the intermediate hash value for the next input {@code value}.
   *
   * @param hash The intermediate hash value.
   * @param value the value to add to the current hash.
   *
   * @returns the updated intermediate hash value
   */
  static update(hash, value) {
    value = Math.imul(value, c1);
    value = value << r1 | value >>> 32 - r1;
    value = Math.imul(value, c2);
    hash = hash ^ value;
    hash = hash << r2 | hash >>> 32 - r2;
    hash = Math.imul(hash, m) + n;
    return hash;
  }
  /**
   * Apply the final computation steps to the intermediate value {@code hash}
   * to form the final result of the MurmurHash 3 hash function.
   *
   * @param hash The intermediate hash value.
   * @param entryCount The number of values added to the hash.
   *
   * @returns the final hash result
   */
  static finish(hash, entryCount) {
    hash ^= entryCount * 4;
    hash ^= hash >>> 16;
    hash = Math.imul(hash, 2246822507);
    hash ^= hash >>> 13;
    hash = Math.imul(hash, 3266489909);
    hash ^= hash >>> 16;
    return hash;
  }
  /**
   * An all-in-one convenience method to compute a hash for a single value.
   *
   * @param value The value to hash.
   * @param seed The seed for the hash value.
   *
   * @returns The computed hash.
   */
  static hashCode(value, seed) {
    return _MurmurHash.finish(_MurmurHash.update(seed ?? _MurmurHash.defaultSeed, value), 1);
  }
};

// src/atn/LexerIndexedCustomAction.ts
var LexerIndexedCustomAction = class _LexerIndexedCustomAction {
  static {
    __name(this, "LexerIndexedCustomAction");
  }
  offset;
  action;
  actionType;
  isPositionDependent = true;
  cachedHashCode;
  constructor(offset, action) {
    this.actionType = action.actionType;
    this.offset = offset;
    this.action = action;
  }
  /**
   * This method calls {@link execute} on the result of {@link getAction}
   * using the provided `lexer`.
   */
  execute(lexer) {
    this.action.execute(lexer);
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      hash = MurmurHash.update(hash, this.offset);
      hash = MurmurHash.updateFromComparable(hash, this.action);
      this.cachedHashCode = MurmurHash.finish(hash, 2);
    }
    return this.cachedHashCode;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _LexerIndexedCustomAction)) {
      return false;
    }
    return this.offset === other.offset && this.action === other.action;
  }
};

// src/atn/LexerActionExecutor.ts
var LexerActionExecutor = class _LexerActionExecutor {
  static {
    __name(this, "LexerActionExecutor");
  }
  lexerActions;
  actionType;
  isPositionDependent = false;
  cachedHashCode;
  /**
   * Represents an executor for a sequence of lexer actions which traversed during
   * the matching operation of a lexer rule (token).
   *
   * The executor tracks position information for position-dependent lexer actions
   * efficiently, ensuring that actions appearing only at the end of the rule do
   * not cause bloating of the {@link DFA} created for the lexer.
   */
  constructor(lexerActions) {
    this.actionType = -1;
    this.lexerActions = lexerActions ?? [];
    return this;
  }
  /**
   * Creates a {@link LexerActionExecutor} which executes the actions for
   * the input `lexerActionExecutor` followed by a specified
   * `lexerAction`.
   *
   * @param lexerActionExecutor The executor for actions already traversed by
   * the lexer while matching a token within a particular
   * {@link LexerATNConfig}. If this is `null`, the method behaves as
   * though it were an empty executor.
   * @param lexerAction The lexer action to execute after the actions
   * specified in `lexerActionExecutor`.
   *
   * @returns {LexerActionExecutor} A {@link LexerActionExecutor} for executing the combine actions
   * of `lexerActionExecutor` and `lexerAction`.
   */
  static append(lexerActionExecutor, lexerAction) {
    if (lexerActionExecutor === null) {
      return new _LexerActionExecutor([lexerAction]);
    }
    const lexerActions = lexerActionExecutor.lexerActions.concat([lexerAction]);
    return new _LexerActionExecutor(lexerActions);
  }
  /**
   * Creates a {@link LexerActionExecutor} which encodes the current offset
   * for position-dependent lexer actions.
   *
   * Normally, when the executor encounters lexer actions where
   * {@link LexerAction//isPositionDependent} returns `true`, it calls
   * {@link IntStream.seek} on the input {@link CharStream} to set the input
   * position to the *end* of the current token. This behavior provides
   * for efficient DFA representation of lexer actions which appear at the end
   * of a lexer rule, even when the lexer rule matches a variable number of
   * characters.
   *
   * Prior to traversing a match transition in the ATN, the current offset
   * from the token start index is assigned to all position-dependent lexer
   * actions which have not already been assigned a fixed offset. By storing
   * the offsets relative to the token start index, the DFA representation of
   * lexer actions which appear in the middle of tokens remains efficient due
   * to sharing among tokens of the same length, regardless of their absolute
   * position in the input stream.
   *
   * If the current executor already has offsets assigned to all
   * position-dependent lexer actions, the method returns `this`.
   *
   * @param offset The current offset to assign to all position-dependent
   * lexer actions which do not already have offsets assigned.
   *
   * @returns {LexerActionExecutor} A {@link LexerActionExecutor} which stores input stream offsets
   * for all position-dependent lexer actions.
   */
  fixOffsetBeforeMatch(offset) {
    let updatedLexerActions = null;
    for (let i = 0; i < this.lexerActions.length; i++) {
      if (this.lexerActions[i].isPositionDependent && !(this.lexerActions[i] instanceof LexerIndexedCustomAction)) {
        if (updatedLexerActions === null) {
          updatedLexerActions = this.lexerActions.concat([]);
        }
        updatedLexerActions[i] = new LexerIndexedCustomAction(
          offset,
          this.lexerActions[i]
        );
      }
    }
    if (updatedLexerActions === null) {
      return this;
    } else {
      return new _LexerActionExecutor(updatedLexerActions);
    }
  }
  /**
   * Execute the actions encapsulated by this executor within the context of a
   * particular {@link Lexer}.
   *
   * This method calls {@link IntStream.seek} to set the position of the
   * `input` {@link CharStream} prior to calling
   * {@link LexerAction.execute} on a position-dependent action. Before the
   * method returns, the input position will be restored to the same position
   * it was in when the method was invoked.
   *
   * @param lexer The lexer instance.
   * @param input The input stream which is the source for the current token.
   * When this method is called, the current {@link IntStream.index} for
   * `input` should be the start of the following token, i.e. 1
   * character past the end of the current token.
   * @param startIndex The token start index. This value may be passed to
   * {@link IntStream.seek} to set the `input` position to the beginning
   * of the token.
   */
  execute(lexer, input, startIndex) {
    if (input === void 0 || startIndex === void 0) {
      return;
    }
    let requiresSeek = false;
    const stopIndex = input.index;
    try {
      for (const lexerAction of this.lexerActions) {
        let action = lexerAction;
        if (lexerAction instanceof LexerIndexedCustomAction) {
          const offset = lexerAction.offset;
          input.seek(startIndex + offset);
          action = lexerAction.action;
          requiresSeek = startIndex + offset !== stopIndex;
        } else if (lexerAction.isPositionDependent) {
          input.seek(stopIndex);
          requiresSeek = false;
        }
        action.execute(lexer);
      }
    } finally {
      if (requiresSeek) {
        input.seek(stopIndex);
      }
    }
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hashCode = MurmurHash.initialize(7);
      for (const lexerAction of this.lexerActions) {
        hashCode = MurmurHash.update(hashCode, lexerAction.hashCode());
      }
      this.cachedHashCode = MurmurHash.finish(hashCode, this.lexerActions.length);
    }
    return this.cachedHashCode;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (this.cachedHashCode !== other.cachedHashCode) {
      return false;
    }
    if (this.lexerActions.length !== other.lexerActions.length) {
      return false;
    }
    return this.lexerActions.every((action, index) => {
      return action.equals(other.lexerActions[index]);
    });
  }
};
