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/misc/InterpreterDataReader.ts
var InterpreterDataReader_exports = {};
__export(InterpreterDataReader_exports, {
  InterpreterDataReader: () => InterpreterDataReader
});
module.exports = __toCommonJS(InterpreterDataReader_exports);

// src/IntStream.ts
var IntStream;
((IntStream2) => {
  IntStream2.EOF = -1;
  IntStream2.UNKNOWN_SOURCE_NAME = "<unknown>";
})(IntStream || (IntStream = {}));

// src/Token.ts
var Token;
((Token2) => {
  Token2.INVALID_TYPE = 0;
  Token2.EPSILON = -2;
  Token2.MIN_USER_TOKEN_TYPE = 1;
  Token2.EOF = IntStream.EOF;
  Token2.DEFAULT_CHANNEL = 0;
  Token2.HIDDEN_CHANNEL = 1;
  Token2.MIN_USER_CHANNEL_VALUE = 2;
})(Token || (Token = {}));
var isToken = /* @__PURE__ */ __name((candidate) => {
  const token = candidate;
  return token.tokenSource !== void 0 && token.channel !== void 0;
}, "isToken");

// src/Vocabulary.ts
var Vocabulary = class _Vocabulary {
  static {
    __name(this, "Vocabulary");
  }
  static EMPTY_NAMES = [];
  /**
   * Gets an empty {@link Vocabulary} instance.
   *
   *
   * No literal or symbol names are assigned to token types, so
   * {@link #getDisplayName(int)} returns the numeric value for all tokens
   * except {@link Token#EOF}.
   */
  static EMPTY_VOCABULARY = new _Vocabulary(_Vocabulary.EMPTY_NAMES, _Vocabulary.EMPTY_NAMES, _Vocabulary.EMPTY_NAMES);
  maxTokenType;
  literalNames;
  symbolicNames;
  displayNames;
  /**
   * Constructs a new instance of {@link Vocabulary} from the specified
   * literal, symbolic, and display token names.
   *
   * @param literalNames The literal names assigned to tokens, or `null`
   * if no literal names are assigned.
   * @param symbolicNames The symbolic names assigned to tokens, or
   * `null` if no symbolic names are assigned.
   * @param displayNames The display names assigned to tokens, or `null`
   * to use the values in `literalNames` and `symbolicNames` as
   * the source of display names, as described in
   * {@link #getDisplayName(int)}.
   */
  constructor(literalNames, symbolicNames, displayNames) {
    this.literalNames = literalNames ?? _Vocabulary.EMPTY_NAMES;
    this.symbolicNames = symbolicNames ?? _Vocabulary.EMPTY_NAMES;
    this.displayNames = displayNames ?? _Vocabulary.EMPTY_NAMES;
    this.maxTokenType = Math.max(this.displayNames.length, Math.max(
      this.literalNames.length,
      this.symbolicNames.length
    )) - 1;
  }
  /**
   * Returns a {@link Vocabulary} instance from the specified set of token
   * names. This method acts as a compatibility layer for the single
   * `tokenNames` array generated by previous releases of ANTLR.
   *
   * The resulting vocabulary instance returns `null` for
   * {@link getLiteralName getLiteralName(int)} and {@link getSymbolicName getSymbolicName(int)}, and the
   * value from `tokenNames` for the display names.
   *
   * @param tokenNames The token names, or `null` if no token names are
   * available.
   * @returns A {@link Vocabulary} instance which uses `tokenNames` for
   * the display names of tokens.
   */
  static fromTokenNames(tokenNames) {
    if (tokenNames == null || tokenNames.length === 0) {
      return _Vocabulary.EMPTY_VOCABULARY;
    }
    const literalNames = [...tokenNames];
    const symbolicNames = [...tokenNames];
    for (let i = 0; i < tokenNames.length; i++) {
      const tokenName = tokenNames[i];
      if (tokenName == null) {
        continue;
      }
      if (tokenName.length > 0) {
        const firstChar = tokenName.codePointAt(0);
        if (firstChar === 39) {
          symbolicNames[i] = null;
          continue;
        } else if (firstChar >= 65 && firstChar <= 90) {
          literalNames[i] = null;
          continue;
        }
      }
      literalNames[i] = null;
      symbolicNames[i] = null;
    }
    return new _Vocabulary(literalNames, symbolicNames, tokenNames);
  }
  getMaxTokenType() {
    return this.maxTokenType;
  }
  getLiteralName(tokenType) {
    if (tokenType >= 0 && tokenType < this.literalNames.length) {
      return this.literalNames[tokenType];
    }
    return null;
  }
  getSymbolicName(tokenType) {
    if (tokenType >= 0 && tokenType < this.symbolicNames.length) {
      return this.symbolicNames[tokenType];
    }
    if (tokenType === Token.EOF) {
      return "EOF";
    }
    return null;
  }
  getDisplayName(tokenType) {
    if (tokenType >= 0 && tokenType < this.displayNames.length) {
      const displayName = this.displayNames[tokenType];
      if (displayName != null) {
        return displayName;
      }
    }
    const literalName = this.getLiteralName(tokenType);
    if (literalName != null) {
      return literalName;
    }
    const symbolicName = this.getSymbolicName(tokenType);
    if (symbolicName != null) {
      return symbolicName;
    }
    return `${tokenType}`;
  }
  getLiteralNames() {
    return this.literalNames;
  }
  getSymbolicNames() {
    return this.symbolicNames;
  }
  getDisplayNames() {
    return this.displayNames;
  }
};

// src/misc/BitSet.ts
var BitSet = class {
  static {
    __name(this, "BitSet");
  }
  data;
  /**
   * Creates a new bit set. All bits are initially `false`.
   *
   * @param data Optional initial data.
   */
  constructor(data) {
    if (data) {
      this.data = new Uint32Array(data.map((value) => {
        return value >>> 0;
      }));
    } else {
      this.data = new Uint32Array(1);
    }
  }
  /**
   * @returns an iterator over all set bits.
   */
  [Symbol.iterator]() {
    const length = this.data.length;
    let currentIndex = 0;
    let currentWord = this.data[currentIndex];
    const words = this.data;
    return {
      [Symbol.iterator]() {
        return this;
      },
      next: /* @__PURE__ */ __name(() => {
        while (currentIndex < length) {
          if (currentWord !== 0) {
            const t = currentWord & -currentWord;
            const value = (currentIndex << 5) + this.bitCount(t - 1);
            currentWord ^= t;
            return { done: false, value };
          } else {
            currentIndex++;
            if (currentIndex < length) {
              currentWord = words[currentIndex];
            }
          }
        }
        return { done: true, value: void 0 };
      }, "next")
    };
  }
  /**
   * Sets a single bit or all of the bits in this `BitSet` to `false`.
   *
   * @param index the index of the bit to be cleared, or undefined to clear all bits.
   */
  clear(index) {
    if (index === void 0) {
      this.data = new Uint32Array();
    } else {
      this.resize(index);
      this.data[index >>> 5] &= ~(1 << index);
    }
  }
  /**
   * Performs a logical **OR** of this bit set with the bit set argument. This bit set is modified so that a bit in it
   * has the value `true` if and only if it either already had the value `true` or the corresponding bit in the bit
   * set argument has the value `true`.
   *
   * @param set the bit set to be ORed with.
   */
  or(set) {
    const minCount = Math.min(this.data.length, set.data.length);
    for (let k = 0; k < minCount; ++k) {
      this.data[k] |= set.data[k];
    }
    if (this.data.length < set.data.length) {
      this.resize((set.data.length << 5) - 1);
      const c = set.data.length;
      for (let k = minCount; k < c; ++k) {
        this.data[k] = set.data[k];
      }
    }
  }
  /**
   * Returns the value of the bit with the specified index. The value is `true` if the bit with the index `bitIndex`
   * is currently set in this `BitSet`; otherwise, the result is `false`.
   *
   * @param index the bit index
   *
   * @returns the value of the bit with the specified index.
   */
  get(index) {
    if (index < 0) {
      throw new RangeError("index cannot be negative");
    }
    const slot = index >>> 5;
    if (slot >= this.data.length) {
      return false;
    }
    return (this.data[slot] & 1 << index % 32) !== 0;
  }
  /**
   * @returns the number of set bits.
   */
  get length() {
    let result = 0;
    const c = this.data.length;
    const w = this.data;
    for (let i = 0; i < c; i++) {
      result += this.bitCount(w[i]);
    }
    return result;
  }
  /**
   * @returns an array with indices of set bits.
   */
  values() {
    const result = new Array(this.length);
    let pos = 0;
    const length = this.data.length;
    for (let k = 0; k < length; ++k) {
      let w = this.data[k];
      while (w !== 0) {
        const t = w & -w;
        result[pos++] = (k << 5) + this.bitCount(t - 1);
        w ^= t;
      }
    }
    return result;
  }
  /**
   * @returns the index of the first bit that is set to `true` that occurs on or after the specified starting index.
   * If no such bit exists then undefined is returned.
   *
   * @param fromIndex the index to start checking from (inclusive)
   */
  nextSetBit(fromIndex) {
    if (fromIndex < 0) {
      throw new RangeError("index cannot be negative");
    }
    for (const index of this) {
      if (index >= fromIndex) {
        return index;
      }
    }
    return void 0;
  }
  /**
   * Sets the bit at the specified index to `true`.
   *
   * @param index a bit index
   */
  set(index) {
    if (index < 0) {
      throw new RangeError("index cannot be negative");
    }
    this.resize(index);
    this.data[index >>> 5] |= 1 << index % 32;
  }
  /**
   * @returns a string representation of this bit set.
   */
  toString() {
    return "{" + this.values().join(", ") + "}";
  }
  resize(index) {
    const count = index + 32 >>> 5;
    if (count <= this.data.length) {
      return;
    }
    const data = new Uint32Array(count);
    data.set(this.data);
    data.fill(0, this.data.length);
    this.data = data;
  }
  bitCount(v) {
    v = v - (v >> 1 & 1431655765);
    v = (v & 858993459) + (v >> 2 & 858993459);
    v = v + (v >> 4) & 252645135;
    v = v + (v >> 8);
    v = v + (v >> 16);
    return v & 63;
  }
};

// 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/misc/ObjectEqualityComparator.ts
var ObjectEqualityComparator = class _ObjectEqualityComparator {
  static {
    __name(this, "ObjectEqualityComparator");
  }
  static instance = new _ObjectEqualityComparator();
  hashCode(obj) {
    if (obj == null) {
      return 0;
    }
    return obj.hashCode();
  }
  equals(a, b) {
    if (a == null) {
      return b == null;
    }
    return a.equals(b);
  }
};

// src/misc/DefaultEqualityComparator.ts
var DefaultEqualityComparator = class _DefaultEqualityComparator {
  static {
    __name(this, "DefaultEqualityComparator");
  }
  static instance = new _DefaultEqualityComparator();
  hashCode(obj) {
    if (obj == null) {
      return 0;
    }
    return ObjectEqualityComparator.instance.hashCode(obj);
  }
  equals(a, b) {
    if (a == null) {
      return b == null;
    }
    if (typeof a === "string" || typeof a === "number") {
      return a === b;
    }
    return ObjectEqualityComparator.instance.equals(a, b);
  }
};

// src/misc/HashSet.ts
var HashSet = class _HashSet {
  static {
    __name(this, "HashSet");
  }
  static defaultLoadFactor = 0.75;
  static initialCapacity = 16;
  // must be power of 2
  comparator;
  buckets;
  threshold;
  /** How many elements in set */
  itemCount = 0;
  constructor(comparatorOrSet, initialCapacity = _HashSet.initialCapacity) {
    if (comparatorOrSet instanceof _HashSet) {
      this.comparator = comparatorOrSet.comparator;
      this.buckets = comparatorOrSet.buckets.slice(0);
      for (let i = 0; i < this.buckets.length; i++) {
        const bucket = this.buckets[i];
        if (bucket) {
          this.buckets[i] = bucket.slice(0);
        }
      }
      this.itemCount = comparatorOrSet.itemCount;
      this.threshold = comparatorOrSet.threshold;
    } else {
      this.comparator = comparatorOrSet ?? DefaultEqualityComparator.instance;
      this.buckets = this.createBuckets(initialCapacity);
      this.threshold = Math.floor(_HashSet.initialCapacity * _HashSet.defaultLoadFactor);
    }
  }
  /**
   * Add `o` to set if not there; return existing value if already
   * there. This method performs the same operation as {@link #add} aside from
   * the return value.
   *
   * @param o the object to add to the set.
   *
   * @returns An existing element that equals to `o` if already in set, otherwise `o`.
   */
  getOrAdd(o) {
    if (this.itemCount > this.threshold) {
      this.expand();
    }
    const b = this.getBucket(o);
    let bucket = this.buckets[b];
    if (!bucket) {
      bucket = [o];
      this.buckets[b] = bucket;
      ++this.itemCount;
      return o;
    }
    for (const existing of bucket) {
      if (this.comparator.equals(existing, o)) {
        return existing;
      }
    }
    bucket.push(o);
    ++this.itemCount;
    return o;
  }
  get(o) {
    if (o == null) {
      return o;
    }
    const b = this.getBucket(o);
    const bucket = this.buckets[b];
    if (!bucket) {
      return void 0;
    }
    for (const e of bucket) {
      if (this.comparator.equals(e, o)) {
        return e;
      }
    }
    return void 0;
  }
  /**
   * Removes the specified element from this set if it is present.
   *
   * @param o object to be removed from this set, if present.
   *
   * @returns `true` if the set contained the specified element.
   */
  remove(o) {
    if (o == null) {
      return false;
    }
    const b = this.getBucket(o);
    const bucket = this.buckets[b];
    if (!bucket) {
      return false;
    }
    for (let i = 0; i < bucket.length; i++) {
      const existing = bucket[i];
      if (this.comparator.equals(existing, o)) {
        bucket.splice(i, 1);
        --this.itemCount;
        return true;
      }
    }
    return false;
  }
  hashCode() {
    let hash = MurmurHash.initialize();
    for (const bucket of this.buckets) {
      if (bucket == null) {
        continue;
      }
      for (const o of bucket) {
        if (o == null) {
          break;
        }
        hash = MurmurHash.update(hash, this.comparator.hashCode(o));
      }
    }
    hash = MurmurHash.finish(hash, this.size);
    return hash;
  }
  equals(o) {
    if (o === this) {
      return true;
    }
    if (!(o instanceof _HashSet)) {
      return false;
    }
    if (o.size !== this.size) {
      return false;
    }
    return this.containsAll(o);
  }
  add(t) {
    const existing = this.getOrAdd(t);
    return existing === t;
  }
  contains(o) {
    return this.containsFast(o);
  }
  containsFast(obj) {
    if (obj == null) {
      return false;
    }
    return this.get(obj) !== void 0;
  }
  *[Symbol.iterator]() {
    yield* this.toArray();
  }
  toArray() {
    const a = new Array(this.size);
    let i = 0;
    for (const bucket of this.buckets) {
      if (bucket == null) {
        continue;
      }
      for (const o of bucket) {
        if (o == null) {
          break;
        }
        a[i++] = o;
      }
    }
    return a;
  }
  containsAll(collection) {
    if (collection instanceof _HashSet) {
      for (const bucket of collection.buckets) {
        if (bucket == null) {
          continue;
        }
        for (const o of bucket) {
          if (o == null) {
            break;
          }
          if (!this.containsFast(o)) {
            return false;
          }
        }
      }
    } else {
      for (const o of collection) {
        if (!this.containsFast(o)) {
          return false;
        }
      }
    }
    return true;
  }
  addAll(c) {
    let changed = false;
    for (const o of c) {
      const existing = this.getOrAdd(o);
      if (existing !== o) {
        changed = true;
      }
    }
    return changed;
  }
  clear() {
    this.buckets = this.createBuckets(_HashSet.initialCapacity);
    this.itemCount = 0;
    this.threshold = Math.floor(_HashSet.initialCapacity * _HashSet.defaultLoadFactor);
  }
  toString() {
    if (this.size === 0) {
      return "{}";
    }
    let buf = "{";
    let first = true;
    for (const bucket of this.buckets) {
      if (bucket == null) {
        continue;
      }
      for (const o of bucket) {
        if (o == null) {
          break;
        }
        if (first) {
          first = false;
        } else {
          buf += ", ";
        }
        buf += o.toString();
      }
    }
    buf += "}";
    return buf;
  }
  toTableString() {
    let buf = "";
    for (const bucket of this.buckets) {
      if (bucket == null) {
        buf += "null\n";
        continue;
      }
      buf += "[";
      let first = true;
      for (const o of bucket) {
        if (first) {
          first = false;
        } else {
          buf += " ";
        }
        if (o == null) {
          buf += "_";
        } else {
          buf += o.toString();
        }
      }
      buf += "]\n";
    }
    return buf;
  }
  getBucket(o) {
    const hash = this.comparator.hashCode(o);
    const b = hash & this.buckets.length - 1;
    return b;
  }
  expand() {
    const old = this.buckets;
    const newCapacity = this.buckets.length * 2;
    const newTable = this.createBuckets(newCapacity);
    this.buckets = newTable;
    this.threshold = Math.floor(newCapacity * _HashSet.defaultLoadFactor);
    for (const bucket of old) {
      if (!bucket) {
        continue;
      }
      for (const o of bucket) {
        const b = this.getBucket(o);
        let newBucket = this.buckets[b];
        if (!newBucket) {
          newBucket = [];
          this.buckets[b] = newBucket;
        }
        newBucket.push(o);
      }
    }
  }
  get size() {
    return this.itemCount;
  }
  get isEmpty() {
    return this.itemCount === 0;
  }
  /**
   * Return an array of `T[]` with length `capacity`.
   *
   * @param capacity the length of the array to return
   * @returns the newly constructed array
   */
  createBuckets(capacity) {
    return new Array(capacity);
  }
};

// src/misc/Interval.ts
var Interval = class _Interval {
  static {
    __name(this, "Interval");
  }
  static INVALID_INTERVAL = new _Interval(-1, -2);
  static INTERVAL_POOL_MAX_VALUE = 1e3;
  static cache = [];
  start;
  stop;
  cachedHashCode;
  constructor(start, stop) {
    this.start = start;
    this.stop = stop;
    this.cachedHashCode = Math.imul(651 + start, 31) + stop;
  }
  /**
   * Creates a new interval from the given values.
   *
   * Interval objects are used readonly so share all with the
   * same single value a==b up to some max size. Use an array as a perfect hash.
   * Return shared object for 0..INTERVAL_POOL_MAX_VALUE or a new
   * Interval object with a..a in it.  On Java.g4, 218623 IntervalSets
   * have a..a (set with 1 element).
   *
   * @param a The start of the interval.
   * @param b The end of the interval (inclusive).
   *
   * @returns A cached or new interval.
   */
  static of(a, b) {
    if (a !== b || a < 0 || a > _Interval.INTERVAL_POOL_MAX_VALUE) {
      return new _Interval(a, b);
    }
    if (!_Interval.cache[a]) {
      _Interval.cache[a] = new _Interval(a, a);
    }
    return _Interval.cache[a];
  }
  equals(o) {
    return this.start === o.start && this.stop === o.stop;
  }
  hashCode() {
    return this.cachedHashCode;
  }
  /** Does this start completely before other? Disjoint */
  startsBeforeDisjoint(other) {
    return this.start < other.start && this.stop < other.start;
  }
  /** Does this start at or before other? Nondisjoint */
  startsBeforeNonDisjoint(other) {
    return this.start <= other.start && this.stop >= other.start;
  }
  /** Does this.start start after other.stop? May or may not be disjoint */
  startsAfter(other) {
    return this.start > other.start;
  }
  /** Does this start completely after other? Disjoint */
  startsAfterDisjoint(other) {
    return this.start > other.stop;
  }
  /** Does this start after other? NonDisjoint */
  startsAfterNonDisjoint(other) {
    return this.start > other.start && this.start <= other.stop;
  }
  /** Are both ranges disjoint? I.e., no overlap? */
  disjoint(other) {
    return this.startsBeforeDisjoint(other) || this.startsAfterDisjoint(other);
  }
  /** Are two intervals adjacent such as 0..41 and 42..42? */
  adjacent(other) {
    return this.start === other.stop + 1 || this.stop === other.start - 1;
  }
  properlyContains(other) {
    return other.start >= this.start && other.stop <= this.stop;
  }
  /** Return the interval computed from combining this and other */
  union(other) {
    return _Interval.of(Math.min(this.start, other.start), Math.max(this.stop, other.stop));
  }
  /** Return the interval in common between this and o */
  intersection(other) {
    return _Interval.of(Math.max(this.start, other.start), Math.min(this.stop, other.stop));
  }
  /**
   * Return the interval with elements from this not in other;
   *  other must not be totally enclosed (properly contained)
   *  within this, which would result in two disjoint intervals
   *  instead of the single one returned by this method.
   */
  differenceNotProperlyContained(other) {
    let diff = null;
    if (other.startsBeforeNonDisjoint(this)) {
      diff = _Interval.of(Math.max(this.start, other.stop + 1), this.stop);
    } else if (other.startsAfterNonDisjoint(this)) {
      diff = _Interval.of(this.start, other.start - 1);
    }
    return diff;
  }
  toString() {
    return `${this.start}..${this.stop}`;
  }
  get length() {
    if (this.stop < this.start) {
      return 0;
    }
    return this.stop - this.start + 1;
  }
};

// src/misc/IntervalSet.ts
var IntervalSet = class _IntervalSet {
  static {
    __name(this, "IntervalSet");
  }
  /** The list of sorted, disjoint intervals. */
  intervals = [];
  cachedHashCode;
  constructor(set) {
    if (set) {
      if (Array.isArray(set)) {
        for (const el of set) {
          this.addOne(el);
        }
      } else {
        this.addSet(set);
      }
    }
  }
  /** Create a set with all ints within range [a..b] (inclusive) */
  static of(a, b) {
    const s = new _IntervalSet();
    s.addRange(a, b);
    return s;
  }
  /** Combine all sets in the array and return the union of them */
  static or(sets) {
    const result = new _IntervalSet();
    for (const set of sets) {
      result.addSet(set);
    }
    return result;
  }
  [Symbol.iterator]() {
    return this.intervals[Symbol.iterator]();
  }
  get(index) {
    return this.intervals[index];
  }
  /**
   * Returns the minimum value contained in the set if not isNil().
   *
   * @returns the minimum value contained in the set.
   */
  get minElement() {
    if (this.intervals.length === 0) {
      return Token.INVALID_TYPE;
    }
    return this.intervals[0].start;
  }
  /**
   * Returns the maximum value contained in the set if not isNil().
   *
   * @returns the maximum value contained in the set.
   */
  get maxElement() {
    if (this.intervals.length === 0) {
      return Token.INVALID_TYPE;
    }
    return this.intervals[this.intervals.length - 1].stop;
  }
  clear() {
    this.cachedHashCode = void 0;
    this.intervals = [];
  }
  /**
   * Add a single element to the set.  An isolated element is stored
   *  as a range el..el.
   */
  addOne(v) {
    this.addInterval(new Interval(v, v));
  }
  /**
   * Add interval; i.e., add all integers from a to b to set.
   *  If b < a, do nothing.
   *  Keep list in sorted order (by left range value).
   *  If overlap, combine ranges. For example,
   *  If this is {1..5, 10..20}, adding 6..7 yields
   *  {1..5, 6..7, 10..20}. Adding 4..8 yields {1..8, 10..20}.
   */
  addRange(l, h) {
    this.addInterval(new Interval(l, h));
  }
  addInterval(addition) {
    this.cachedHashCode = void 0;
    if (this.intervals.length === 0) {
      this.intervals.push(addition);
    } else {
      for (let pos = 0; pos < this.intervals.length; pos++) {
        const existing = this.intervals[pos];
        if (addition.equals(existing)) {
          return;
        }
        if (addition.adjacent(existing) || !addition.disjoint(existing)) {
          const bigger = addition.union(existing);
          this.intervals[pos] = bigger;
          for (let sub = pos + 1; sub < this.intervals.length; ) {
            const next = this.intervals[sub];
            if (!bigger.adjacent(next) && bigger.disjoint(next)) {
              break;
            }
            this.intervals.splice(sub, 1);
            this.intervals[pos] = bigger.union(next);
          }
          return;
        }
        if (addition.startsBeforeDisjoint(existing)) {
          this.intervals.splice(pos, 0, addition);
          return;
        }
      }
      this.intervals.push(addition);
    }
  }
  addSet(other) {
    other.intervals.forEach((toAdd) => {
      return this.addInterval(toAdd);
    }, this);
    return this;
  }
  complementWithVocabulary(vocabulary) {
    const result = new _IntervalSet();
    if (!vocabulary) {
      return result;
    }
    if (vocabulary.length === 0) {
      return result;
    }
    result.addSet(vocabulary);
    return result.subtract(this);
  }
  complement(minElement, maxElement) {
    const result = new _IntervalSet();
    result.addInterval(new Interval(minElement, maxElement));
    return result.subtract(this);
  }
  /** combine all sets in the array returned the or'd value */
  or(sets) {
    const result = new _IntervalSet();
    result.addSet(this);
    sets.forEach((set) => {
      return result.addSet(set);
    });
    return result;
  }
  and(other) {
    if (other.length === 0) {
      return new _IntervalSet();
    }
    const myIntervals = this.intervals;
    const theirIntervals = other.intervals;
    let intersection;
    const mySize = myIntervals.length;
    const theirSize = theirIntervals.length;
    let i = 0;
    let j = 0;
    while (i < mySize && j < theirSize) {
      const mine = myIntervals[i];
      const theirs = theirIntervals[j];
      if (mine.startsBeforeDisjoint(theirs)) {
        i++;
      } else if (theirs.startsBeforeDisjoint(mine)) {
        j++;
      } else if (mine.properlyContains(theirs)) {
        if (!intersection) {
          intersection = new _IntervalSet();
        }
        intersection.addInterval(mine.intersection(theirs));
        j++;
      } else if (theirs.properlyContains(mine)) {
        if (!intersection) {
          intersection = new _IntervalSet();
        }
        intersection.addInterval(mine.intersection(theirs));
        i++;
      } else if (!mine.disjoint(theirs)) {
        if (!intersection) {
          intersection = new _IntervalSet();
        }
        intersection.addInterval(mine.intersection(theirs));
        if (mine.startsAfterNonDisjoint(theirs)) {
          j++;
        } else if (theirs.startsAfterNonDisjoint(mine)) {
          i++;
        }
      }
    }
    if (!intersection) {
      return new _IntervalSet();
    }
    return intersection;
  }
  /**
   * Compute the set difference between two interval sets. The specific
   * operation is `left - right`. If either of the input sets is
   * `null`, it is treated as though it was an empty set.
   */
  subtract(other) {
    if (this.length === 0) {
      return new _IntervalSet();
    }
    const result = new _IntervalSet(this);
    if (other.length === 0) {
      return result;
    }
    let resultI = 0;
    let rightI = 0;
    while (resultI < result.intervals.length && rightI < other.intervals.length) {
      const resultInterval = result.intervals[resultI];
      const rightInterval = other.intervals[rightI];
      if (rightInterval.stop < resultInterval.start) {
        rightI++;
        continue;
      }
      if (rightInterval.start > resultInterval.stop) {
        resultI++;
        continue;
      }
      let beforeCurrent;
      let afterCurrent;
      if (rightInterval.start > resultInterval.start) {
        beforeCurrent = new Interval(resultInterval.start, rightInterval.start - 1);
      }
      if (rightInterval.stop < resultInterval.stop) {
        afterCurrent = new Interval(rightInterval.stop + 1, resultInterval.stop);
      }
      if (beforeCurrent) {
        if (afterCurrent) {
          result.intervals[resultI] = beforeCurrent;
          result.intervals.splice(resultI + 1, 0, afterCurrent);
          resultI++;
          rightI++;
        } else {
          result.intervals[resultI] = beforeCurrent;
          resultI++;
        }
      } else {
        if (afterCurrent) {
          result.intervals[resultI] = afterCurrent;
          rightI++;
        } else {
          result.intervals.splice(resultI, 1);
        }
      }
    }
    return result;
  }
  contains(el) {
    const n2 = this.intervals.length;
    let l = 0;
    let r = n2 - 1;
    while (l <= r) {
      const m2 = Math.floor((l + r) / 2);
      const interval = this.intervals[m2];
      if (interval.stop < el) {
        l = m2 + 1;
      } else if (interval.start > el) {
        r = m2 - 1;
      } else {
        return true;
      }
    }
    return false;
  }
  removeRange(toRemove) {
    this.cachedHashCode = void 0;
    if (toRemove.start === toRemove.stop) {
      this.removeOne(toRemove.start);
    } else if (this.intervals !== null) {
      let pos = 0;
      for (const existing of this.intervals) {
        if (toRemove.stop <= existing.start) {
          return;
        } else if (toRemove.start > existing.start && toRemove.stop < existing.stop) {
          this.intervals[pos] = new Interval(existing.start, toRemove.start);
          const x = new Interval(toRemove.stop, existing.stop);
          this.intervals.splice(pos, 0, x);
          return;
        } else if (toRemove.start <= existing.start && toRemove.stop >= existing.stop) {
          this.intervals.splice(pos, 1);
          pos = pos - 1;
        } else if (toRemove.start < existing.stop) {
          this.intervals[pos] = new Interval(existing.start, toRemove.start);
        } else if (toRemove.stop < existing.stop) {
          this.intervals[pos] = new Interval(toRemove.stop, existing.stop);
        }
        pos += 1;
      }
    }
  }
  removeOne(value) {
    this.cachedHashCode = void 0;
    for (let i = 0; i < this.intervals.length; i++) {
      const existing = this.intervals[i];
      if (value < existing.start) {
        return;
      } else if (value === existing.start && value === existing.stop) {
        this.intervals.splice(i, 1);
        return;
      } else if (value === existing.start) {
        this.intervals[i] = new Interval(existing.start + 1, existing.stop);
        return;
      } else if (value === existing.stop) {
        this.intervals[i] = new Interval(existing.start, existing.stop - 1);
        return;
      } else if (value < existing.stop) {
        const replace = new Interval(existing.start, value - 1);
        this.intervals[i] = new Interval(value + 1, existing.stop);
        this.intervals.splice(i, 0, replace);
        return;
      }
    }
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      for (const interval of this.intervals) {
        hash = MurmurHash.update(hash, interval.start);
        hash = MurmurHash.update(hash, interval.stop);
      }
      this.cachedHashCode = MurmurHash.finish(hash, this.intervals.length * 2);
    }
    return this.cachedHashCode;
  }
  /**
   * Are two IntervalSets equal? Because all intervals are sorted and disjoint, equals is a simple linear walk over
   * both lists to make sure they are the same. Interval.equals() is used by the List.equals() method to check
   * the ranges.
   */
  equals(other) {
    if (this === other) {
      return true;
    }
    if (this.intervals.length !== other.intervals.length) {
      return false;
    }
    for (let i = 0; i < this.intervals.length; i++) {
      if (!this.intervals[i].equals(other.intervals[i])) {
        return false;
      }
    }
    return true;
  }
  toString(elementsAreChar) {
    if (this.intervals.length === 0) {
      return "{}";
    }
    let result = "";
    if (this.length > 1) {
      result += "{";
    }
    for (let i = 0; i < this.intervals.length; ++i) {
      const interval = this.intervals[i];
      const start = interval.start;
      const stop = interval.stop;
      if (start === stop) {
        if (start === Token.EOF) {
          result += "<EOF>";
        } else if (elementsAreChar) {
          result += "'" + String.fromCodePoint(start) + "'";
        } else {
          result += start;
        }
      } else {
        if (elementsAreChar) {
          result += "'" + String.fromCodePoint(start) + "'..'" + String.fromCodePoint(stop) + "'";
        } else {
          result += start + ".." + stop;
        }
      }
      if (i < this.intervals.length - 1) {
        result += ", ";
      }
    }
    if (this.length > 1) {
      result += "}";
    }
    return result;
  }
  toStringWithVocabulary(vocabulary) {
    if (this.intervals.length === 0) {
      return "{}";
    }
    let result = "";
    if (this.length > 1) {
      result += "{";
    }
    for (let i = 0; i < this.intervals.length; ++i) {
      const interval = this.intervals[i];
      const start = interval.start;
      const stop = interval.stop;
      if (start === stop) {
        if (start === Token.EOF) {
          result += "<EOF>";
        } else {
          result += this.elementName(vocabulary, start);
        }
      } else {
        for (let i2 = start; i2 <= stop; ++i2) {
          if (i2 > start) {
            result += ", ";
          }
          result += this.elementName(vocabulary, i2);
        }
      }
      if (i < this.intervals.length - 1) {
        result += ", ";
      }
    }
    if (this.length > 1) {
      result += "}";
    }
    return result;
  }
  toStringWithRuleNames(ruleNames) {
    if (this.intervals.length === 0) {
      return "{}";
    }
    let result = "";
    if (this.length > 1) {
      result += "{";
    }
    const vocabulary = Vocabulary.fromTokenNames(ruleNames);
    for (let i = 0; i < this.intervals.length; ++i) {
      const interval = this.intervals[i];
      const start = interval.start;
      const stop = interval.stop;
      if (start === stop) {
        if (start === Token.EOF) {
          result += "<EOF>";
        } else {
          result += this.elementName(vocabulary, start);
        }
      } else {
        for (let i2 = start; i2 <= stop; ++i2) {
          if (i2 > start) {
            result += ", ";
          }
          result += this.elementName(vocabulary, i2);
        }
      }
      if (i < this.intervals.length - 1) {
        result += ", ";
      }
    }
    if (this.length > 1) {
      result += "}";
    }
    return result;
  }
  toArray() {
    const data = [];
    for (const interval of this.intervals) {
      for (let j = interval.start; j <= interval.stop; j++) {
        data.push(j);
      }
    }
    return data;
  }
  /** @returns the number of elements in this set. */
  get length() {
    let result = 0;
    for (const interval of this.intervals) {
      result += interval.length;
    }
    return result;
  }
  elementName(vocabulary, token) {
    if (token === Token.EOF) {
      return "<EOF>";
    }
    if (token === Token.EPSILON) {
      return "<EPSILON>";
    }
    return vocabulary.getDisplayName(token);
  }
};

// src/utils/helpers.ts
var equalArrays = /* @__PURE__ */ __name((a, b) => {
  if (a === b) {
    return true;
  }
  if (a.length !== b.length) {
    return false;
  }
  for (let i = 0; i < a.length; i++) {
    const left = a[i];
    const right = b[i];
    if (left === right) {
      continue;
    }
    if (!left || !left.equals(right)) {
      return false;
    }
  }
  return true;
}, "equalArrays");
var escapeWhitespace = /* @__PURE__ */ __name((s, escapeSpaces = false) => {
  s = s.replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
  if (escapeSpaces) {
    s = s.replace(/ /g, "\xB7");
  }
  return s;
}, "escapeWhitespace");

// src/atn/SemanticContext.ts
var SemanticContext = class _SemanticContext {
  static {
    __name(this, "SemanticContext");
  }
  cachedHashCode;
  static andContext(a, b) {
    if (a === null || a === _SemanticContext.NONE) {
      return b;
    }
    if (b === null || b === _SemanticContext.NONE) {
      return a;
    }
    const result = new AND(a, b);
    if (result.operands.length === 1) {
      return result.operands[0];
    }
    return result;
  }
  static orContext(a, b) {
    if (a === null) {
      return b;
    }
    if (b === null) {
      return a;
    }
    if (a === _SemanticContext.NONE || b === _SemanticContext.NONE) {
      return _SemanticContext.NONE;
    }
    const result = new OR(a, b);
    if (result.operands.length === 1) {
      return result.operands[0];
    } else {
      return result;
    }
  }
  static filterPrecedencePredicates(set) {
    const result = [];
    for (const context of set) {
      if (context instanceof _SemanticContext.PrecedencePredicate) {
        result.push(context);
      }
    }
    return result;
  }
  /**
   * Evaluate the precedence predicates for the context and reduce the result.
   *
   * @param _parser The parser instance.
   * @param _parserCallStack The current parser context object.
   * @returns The simplified semantic context after precedence predicates are
   * evaluated, which will be one of the following values.
   * - {@link NONE}: if the predicate simplifies to `true` after
   * precedence predicates are evaluated.
   * - `null`: if the predicate simplifies to `false` after
   * precedence predicates are evaluated.
   * - `this`: if the semantic context is not changed as a result of
   * precedence predicate evaluation.
   * - A non-`null` {@link SemanticContext}: the new simplified
   * semantic context after precedence predicates are evaluated.
   */
  evalPrecedence(_parser, _parserCallStack) {
    return this;
  }
};
var AND = class _AND extends SemanticContext {
  static {
    __name(this, "AND");
  }
  operands;
  /**
   * A semantic context which is true whenever none of the contained contexts
   * is false
   */
  constructor(a, b) {
    super();
    const operands = new HashSet();
    if (a instanceof _AND) {
      a.operands.forEach((o) => {
        operands.add(o);
      });
    } else {
      operands.add(a);
    }
    if (b instanceof _AND) {
      b.operands.forEach((o) => {
        operands.add(o);
      });
    } else {
      operands.add(b);
    }
    const precedencePredicates = SemanticContext.filterPrecedencePredicates(operands);
    if (precedencePredicates.length > 0) {
      let reduced = null;
      precedencePredicates.forEach((p) => {
        if (reduced === null || p.precedence < reduced.precedence) {
          reduced = p;
        }
      });
      if (reduced) {
        operands.add(reduced);
      }
    }
    this.operands = operands.toArray();
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _AND)) {
      return false;
    }
    return equalArrays(this.operands, other.operands);
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      for (const operand of this.operands) {
        hash = MurmurHash.updateFromComparable(hash, operand);
      }
      hash = MurmurHash.update(hash, 3813686060);
      this.cachedHashCode = MurmurHash.finish(hash, this.operands.length + 1);
    }
    return this.cachedHashCode;
  }
  /**
   * {@inheritDoc}
   *
   *
   * The evaluation of predicates by this context is short-circuiting, but
   * unordered.
   */
  evaluate(parser, parserCallStack) {
    for (const operand of this.operands) {
      if (!operand.evaluate(parser, parserCallStack)) {
        return false;
      }
    }
    return true;
  }
  evalPrecedence(parser, parserCallStack) {
    let differs = false;
    const operands = [];
    for (const context of this.operands) {
      const evaluated = context.evalPrecedence(parser, parserCallStack);
      differs ||= evaluated !== context;
      if (evaluated === null) {
        return null;
      } else if (evaluated !== SemanticContext.NONE) {
        operands.push(evaluated);
      }
    }
    if (!differs) {
      return this;
    }
    if (operands.length === 0) {
      return SemanticContext.NONE;
    }
    let result = null;
    operands.forEach((o) => {
      result = result === null ? o : SemanticContext.andContext(result, o);
    });
    return result;
  }
  toString() {
    const s = this.operands.map((o) => {
      return o.toString();
    });
    return (s.length > 3 ? s.slice(3) : s).join("&&");
  }
};
var OR = class _OR extends SemanticContext {
  static {
    __name(this, "OR");
  }
  operands;
  /**
   * A semantic context which is true whenever at least one of the contained
   * contexts is true
   */
  constructor(a, b) {
    super();
    const operands = new HashSet();
    if (a instanceof _OR) {
      a.operands.forEach((o) => {
        operands.add(o);
      });
    } else {
      operands.add(a);
    }
    if (b instanceof _OR) {
      b.operands.forEach((o) => {
        operands.add(o);
      });
    } else {
      operands.add(b);
    }
    const precedencePredicates = SemanticContext.filterPrecedencePredicates(operands);
    if (precedencePredicates.length > 0) {
      const s = precedencePredicates.sort((a2, b2) => {
        return a2.compareTo(b2);
      });
      const reduced = s[s.length - 1];
      operands.add(reduced);
    }
    this.operands = operands.toArray();
  }
  equals(other) {
    if (this === other) {
      return true;
    } else if (!(other instanceof _OR)) {
      return false;
    } else {
      return equalArrays(this.operands, other.operands);
    }
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      for (const operand of this.operands) {
        hash = MurmurHash.updateFromComparable(hash, operand);
      }
      hash = MurmurHash.update(hash, 3383313031);
      this.cachedHashCode = MurmurHash.finish(hash, this.operands.length + 1);
    }
    return this.cachedHashCode;
  }
  /**
   * The evaluation of predicates by this context is short-circuiting, but unordered.
   */
  evaluate(parser, parserCallStack) {
    for (const operand of this.operands) {
      if (operand.evaluate(parser, parserCallStack)) {
        return true;
      }
    }
    return false;
  }
  evalPrecedence(parser, parserCallStack) {
    let differs = false;
    const operands = [];
    for (const context of this.operands) {
      const evaluated = context.evalPrecedence(parser, parserCallStack);
      differs ||= evaluated !== context;
      if (evaluated === SemanticContext.NONE) {
        return SemanticContext.NONE;
      } else if (evaluated !== null) {
        operands.push(evaluated);
      }
    }
    if (!differs) {
      return this;
    }
    if (operands.length === 0) {
      return null;
    }
    let result = null;
    operands.forEach((o) => {
      result = result === null ? o : SemanticContext.orContext(result, o);
    });
    return result;
  }
  toString() {
    const s = this.operands.map((o) => {
      return o.toString();
    });
    return (s.length > 3 ? s.slice(3) : s).join("||");
  }
};
((SemanticContext2) => {
  class Predicate extends SemanticContext2 {
    static {
      __name(this, "Predicate");
    }
    ruleIndex;
    predIndex;
    isCtxDependent;
    // e.g., $i ref in pred
    constructor(ruleIndex, predIndex, isCtxDependent) {
      super();
      this.ruleIndex = ruleIndex ?? -1;
      this.predIndex = predIndex ?? -1;
      this.isCtxDependent = isCtxDependent ?? false;
    }
    evaluate(parser, outerContext) {
      const localctx = this.isCtxDependent ? outerContext : null;
      return parser.sempred(localctx, this.ruleIndex, this.predIndex);
    }
    hashCode() {
      if (this.cachedHashCode === void 0) {
        let hashCode = MurmurHash.initialize();
        hashCode = MurmurHash.update(hashCode, this.ruleIndex);
        hashCode = MurmurHash.update(hashCode, this.predIndex);
        hashCode = MurmurHash.update(hashCode, this.isCtxDependent ? 1 : 0);
        hashCode = MurmurHash.finish(hashCode, 3);
        this.cachedHashCode = hashCode;
      }
      return this.cachedHashCode;
    }
    equals(other) {
      if (this === other) {
        return true;
      }
      return this.ruleIndex === other.ruleIndex && this.predIndex === other.predIndex && this.isCtxDependent === other.isCtxDependent;
    }
    toString() {
      return "{" + this.ruleIndex + ":" + this.predIndex + "}?";
    }
  }
  SemanticContext2.Predicate = Predicate;
  class PrecedencePredicate extends SemanticContext2 {
    static {
      __name(this, "PrecedencePredicate");
    }
    precedence;
    constructor(precedence) {
      super();
      this.precedence = precedence ?? 0;
    }
    evaluate(parser, outerContext) {
      return parser.precpred(outerContext, this.precedence);
    }
    evalPrecedence(parser, outerContext) {
      if (parser.precpred(outerContext ?? null, this.precedence)) {
        return SemanticContext2.NONE;
      }
      return null;
    }
    compareTo(other) {
      return this.precedence - other.precedence;
    }
    hashCode() {
      return 31 + this.precedence;
    }
    equals(other) {
      if (this === other) {
        return true;
      }
      return this.precedence === other.precedence;
    }
    toString() {
      return "{" + this.precedence + ">=prec}?";
    }
  }
  SemanticContext2.PrecedencePredicate = PrecedencePredicate;
  SemanticContext2.NONE = new Predicate();
})(SemanticContext || (SemanticContext = {}));

// src/atn/ATNConfig.ts
var ATNConfig = class _ATNConfig {
  static {
    __name(this, "ATNConfig");
  }
  /** The ATN state associated with this configuration */
  state;
  /** What alt (or lexer rule) is predicted by this configuration */
  alt;
  /**
   * We cannot execute predicates dependent upon local context unless
   * we know for sure we are in the correct context. Because there is
   * no way to do this efficiently, we simply cannot evaluate
   * dependent predicates unless we are in the rule that initially
   * invokes the ATN simulator.
   *
   * closure() tracks the depth of how far we dip into the outer context:
   * depth > 0.
   */
  reachesIntoOuterContext = false;
  // Not used in hash code.
  precedenceFilterSuppressed = false;
  // Not used in hash code.
  get semanticContext() {
    return this.#semanticContext;
  }
  cachedHashCode;
  // Shared with LexerATNConfig.
  /**
   * The syntactic context is a graph-structured stack node whose
   * path(s) to the root is the rule invocation(s)
   * chain used to arrive at the state.  The semantic context is
   * the tree of semantic predicates encountered before reaching
   * an ATN state
   */
  #context = null;
  #semanticContext;
  /** Never create config classes directly. Use the factory methods below. */
  constructor(c, state, context, semanticContext) {
    this.state = state;
    this.alt = c.alt;
    this.context = context;
    this.#semanticContext = semanticContext ?? SemanticContext.NONE;
    this.reachesIntoOuterContext = c.reachesIntoOuterContext;
    if (c.precedenceFilterSuppressed !== void 0) {
      this.precedenceFilterSuppressed = c.precedenceFilterSuppressed;
    }
  }
  static duplicate(old, semanticContext) {
    return new _ATNConfig(old, old.state, old.context, semanticContext ?? old.semanticContext);
  }
  static createWithContext(state, alt, context, semanticContext) {
    return new _ATNConfig({ alt }, state, context, semanticContext);
  }
  static createWithConfig(state, config, context) {
    return new _ATNConfig(config, state, context ?? config.context, config.semanticContext);
  }
  static createWithSemanticContext(state, c, semanticContext) {
    return new _ATNConfig(c, state ?? c.state, c.context, semanticContext);
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hashCode = MurmurHash.initialize(7);
      hashCode = MurmurHash.update(hashCode, this.state.stateNumber);
      hashCode = MurmurHash.update(hashCode, this.alt);
      hashCode = MurmurHash.updateFromComparable(hashCode, this.#context);
      hashCode = MurmurHash.updateFromComparable(hashCode, this.semanticContext);
      hashCode = MurmurHash.finish(hashCode, 4);
      this.cachedHashCode = hashCode;
    }
    return this.cachedHashCode;
  }
  /**
   * The stack of invoking states leading to the rule/states associated
   * with this config.  We track only those contexts pushed during
   * execution of the ATN simulator.
   */
  get context() {
    return this.#context;
  }
  set context(context) {
    this.#context = context;
    this.cachedHashCode = void 0;
  }
  /**
   * An ATN configuration is equal to another if both have
   * the same state, they predict the same alternative, and
   * syntactic/semantic contexts are the same.
   */
  equals(other) {
    if (this === other) {
      return true;
    }
    return this.state.stateNumber === other.state.stateNumber && this.alt === other.alt && (this.context === null ? other.context === null : this.context.equals(other.context)) && this.semanticContext.equals(other.semanticContext) && this.precedenceFilterSuppressed === other.precedenceFilterSuppressed;
  }
  toString(_recog, showAlt = true) {
    let alt = "";
    if (showAlt) {
      alt = "," + this.alt;
    }
    return "(" + this.state + alt + (this.context !== null ? ",[" + this.context.toString() + "]" : "") + (this.semanticContext !== SemanticContext.NONE ? "," + this.semanticContext.toString() : "") + (this.reachesIntoOuterContext ? ",up=" + this.reachesIntoOuterContext : "") + ")";
  }
};

// src/atn/ATNState.ts
var ATNState = class _ATNState {
  static {
    __name(this, "ATNState");
  }
  static INVALID_STATE_NUMBER = -1;
  static INVALID_TYPE = 0;
  static BASIC = 1;
  static RULE_START = 2;
  static BLOCK_START = 3;
  static PLUS_BLOCK_START = 4;
  static STAR_BLOCK_START = 5;
  static TOKEN_START = 6;
  static RULE_STOP = 7;
  static BLOCK_END = 8;
  static STAR_LOOP_BACK = 9;
  static STAR_LOOP_ENTRY = 10;
  static PLUS_LOOP_BACK = 11;
  static LOOP_END = 12;
  static stateType = _ATNState.INVALID_STATE_NUMBER;
  stateNumber = 0;
  ruleIndex = 0;
  // at runtime, we don't have Rule objects
  epsilonOnlyTransitions = false;
  /** Used to cache lookahead during parsing, not used during construction */
  nextTokenWithinRule;
  /** Track the transitions emanating from this ATN state. */
  transitions = [];
  hashCode() {
    return this.stateNumber;
  }
  equals(other) {
    return this.stateNumber === other.stateNumber;
  }
  toString() {
    return `${this.stateNumber}`;
  }
  addTransitionAtIndex(index, transition) {
    if (this.transitions.length === 0) {
      this.epsilonOnlyTransitions = transition.isEpsilon;
    } else if (this.epsilonOnlyTransitions !== transition.isEpsilon) {
      this.epsilonOnlyTransitions = false;
    }
    this.transitions.splice(index, 1, transition);
  }
  addTransition(transition) {
    if (this.transitions.length === 0) {
      this.epsilonOnlyTransitions = transition.isEpsilon;
    } else if (this.epsilonOnlyTransitions !== transition.isEpsilon) {
      this.epsilonOnlyTransitions = false;
    }
    this.transitions.push(transition);
  }
  setTransition(i, e) {
    this.transitions.splice(i, 1, e);
  }
  removeTransition(index) {
    const t = this.transitions.splice(index, 1);
    return t[0];
  }
};

// src/atn/PredictionContext.ts
var PredictionContext = class _PredictionContext {
  static {
    __name(this, "PredictionContext");
  }
  /**
   * Represents `$` in an array in full context mode, when `$`
   * doesn't mean wildcard: `$ + x = [$,x]`. Here,
   * `$` = {@link EMPTY_RETURN_STATE}.
   */
  static EMPTY_RETURN_STATE = 2147483647;
  static traceATNSimulator = false;
  cachedHashCode;
  constructor(cachedHashCode) {
    this.cachedHashCode = cachedHashCode;
  }
  static calculateEmptyHashCode() {
    let hash = MurmurHash.initialize(31);
    hash = MurmurHash.finish(hash, 0);
    return hash;
  }
  static calculateHashCodeSingle(parent, returnState) {
    let hash = MurmurHash.initialize(31);
    hash = MurmurHash.updateFromComparable(hash, parent);
    hash = MurmurHash.update(hash, returnState);
    hash = MurmurHash.finish(hash, 2);
    return hash;
  }
  static calculateHashCodeList(parents, returnStates) {
    let hash = MurmurHash.initialize(31);
    for (const parent of parents) {
      hash = MurmurHash.updateFromComparable(hash, parent);
    }
    for (const returnState of returnStates) {
      hash = MurmurHash.update(hash, returnState);
    }
    hash = MurmurHash.finish(hash, 2 * parents.length);
    return hash;
  }
  isEmpty() {
    return false;
  }
  hasEmptyPath() {
    return this.getReturnState(this.length - 1) === _PredictionContext.EMPTY_RETURN_STATE;
  }
  hashCode() {
    return this.cachedHashCode;
  }
  toString(_recog) {
    return "";
  }
};

// src/atn/SingletonPredictionContext.ts
var SingletonPredictionContext = class _SingletonPredictionContext extends PredictionContext {
  static {
    __name(this, "SingletonPredictionContext");
  }
  parent;
  returnState;
  constructor(parent, returnState) {
    super(
      parent ? PredictionContext.calculateHashCodeSingle(parent, returnState) : PredictionContext.calculateEmptyHashCode()
    );
    this.parent = parent ?? null;
    this.returnState = returnState;
  }
  getParent(_index) {
    return this.parent;
  }
  getReturnState(_index) {
    return this.returnState;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _SingletonPredictionContext)) {
      return false;
    }
    if (this.hashCode() !== other.hashCode()) {
      return false;
    }
    if (this.returnState !== other.returnState) {
      return false;
    }
    if (this.parent == null) {
      return other.parent == null;
    }
    return this.parent.equals(other.parent);
  }
  toString() {
    const up = this.parent === null ? "" : this.parent.toString();
    if (up.length === 0) {
      if (this.returnState === PredictionContext.EMPTY_RETURN_STATE) {
        return "$";
      }
      return "" + this.returnState;
    } else {
      return "" + this.returnState + " " + up;
    }
  }
  get length() {
    return 1;
  }
};

// src/atn/EmptyPredictionContext.ts
var EmptyPredictionContext = class _EmptyPredictionContext extends SingletonPredictionContext {
  static {
    __name(this, "EmptyPredictionContext");
  }
  /**
   * Represents `$` in local context prediction, which means wildcard.
   * `*+x = *`.
   */
  static instance = new _EmptyPredictionContext();
  constructor() {
    super(void 0, PredictionContext.EMPTY_RETURN_STATE);
  }
  isEmpty() {
    return true;
  }
  getParent() {
    return null;
  }
  getReturnState() {
    return this.returnState;
  }
  equals(other) {
    return this === other;
  }
  toString() {
    return "$";
  }
};

// src/atn/Transition.ts
var Transition = class {
  static {
    __name(this, "Transition");
  }
  static INVALID = 0;
  static EPSILON = 1;
  static RANGE = 2;
  static RULE = 3;
  static PREDICATE = 4;
  // e.g., {isType(input.LT(1))}
  static ATOM = 5;
  static ACTION = 6;
  static SET = 7;
  // ~(A|B) or ~atom, wildcard, which convert to next
  static NOT_SET = 8;
  static WILDCARD = 9;
  static PRECEDENCE = 10;
  /** The target of this transition. */
  target;
  constructor(target) {
    this.target = target;
  }
  /**
   * Determines if the transition is an "epsilon" transition.
   *
   * The default implementation returns `false`.
   *
   * @returns `true` if traversing this transition in the ATN does not
   * consume an input symbol; otherwise, `false` if traversing this
   * transition consumes (matches) an input symbol.
   */
  get isEpsilon() {
    return false;
  }
  get label() {
    return null;
  }
  toString() {
    return "";
  }
};

// src/atn/SetTransition.ts
var SetTransition = class extends Transition {
  static {
    __name(this, "SetTransition");
  }
  set;
  constructor(target, set) {
    super(target);
    if (set) {
      this.set = set;
    } else {
      this.set = IntervalSet.of(Token.INVALID_TYPE, Token.INVALID_TYPE);
    }
  }
  get transitionType() {
    return Transition.SET;
  }
  get label() {
    return this.set;
  }
  matches(symbol, _minVocabSymbol, _maxVocabSymbol) {
    return this.set.contains(symbol);
  }
  toString() {
    return this.set.toString();
  }
};

// src/atn/NotSetTransition.ts
var NotSetTransition = class extends SetTransition {
  static {
    __name(this, "NotSetTransition");
  }
  get transitionType() {
    return Transition.NOT_SET;
  }
  matches(symbol, minVocabSymbol, maxVocabSymbol) {
    return symbol >= minVocabSymbol && symbol <= maxVocabSymbol && !super.matches(symbol, minVocabSymbol, maxVocabSymbol);
  }
  toString() {
    return "~" + super.toString();
  }
};

// src/tree/TerminalNode.ts
var TerminalNode = class {
  static {
    __name(this, "TerminalNode");
  }
  parent = null;
  symbol;
  constructor(symbol) {
    this.symbol = symbol;
  }
  getChild(_i) {
    return null;
  }
  getSymbol() {
    return this.symbol;
  }
  getPayload() {
    return this.symbol;
  }
  getSourceInterval() {
    if (this.symbol === null) {
      return Interval.INVALID_INTERVAL;
    }
    const tokenIndex = this.symbol.tokenIndex;
    return new Interval(tokenIndex, tokenIndex);
  }
  getChildCount() {
    return 0;
  }
  accept(visitor) {
    return visitor.visitTerminal(this);
  }
  getText() {
    return this.symbol?.text ?? "";
  }
  toString() {
    if (this.symbol?.type === Token.EOF) {
      return "<EOF>";
    } else {
      return this.symbol?.text ?? "";
    }
  }
  toStringTree() {
    return this.toString();
  }
};

// src/tree/ErrorNode.ts
var ErrorNode = class extends TerminalNode {
  static {
    __name(this, "ErrorNode");
  }
  accept(visitor) {
    return visitor.visitErrorNode(this);
  }
};

// src/CommonToken.ts
var CommonToken = class _CommonToken {
  static {
    __name(this, "CommonToken");
  }
  /**
   * An empty tuple which is used as the default value of
   * {@link source} for tokens that do not have a source.
   */
  // eslint-disable-next-line @typescript-eslint/naming-convention
  static EMPTY_SOURCE = [null, null];
  /**
   * These properties share a field to reduce the memory footprint of
   * {@link CommonToken}. Tokens created by a {@link CommonTokenFactory} from
   * the same source and input stream share a reference to the same
   * {@link Pair} containing these values.
   */
  source;
  tokenIndex;
  start;
  stop;
  /**
   * This is the backing field for {@link #getType} and {@link #setType}.
   */
  type;
  /**
   * The (one-based) line number on which the 1st character of this token was.
   */
  line;
  /**
   * The zero-based index of the first character position in its line.
   */
  column;
  /**
   * The token's channel.
   */
  channel;
  /**
   * This is the backing field for {@link getText} when the token text is
   * explicitly set in the constructor or via {@link setText}.
   */
  #text;
  constructor(details) {
    this.type = details.type;
    this.source = details.source;
    this.tokenIndex = details.tokenIndex ?? -1;
    this.line = details.line ?? 0;
    this.column = details.column ?? -1;
    this.channel = details.channel ?? Token.DEFAULT_CHANNEL;
    this.start = details.start ?? 0;
    this.stop = details.stop ?? 0;
    this.#text = details.text;
    if (details.line === void 0 && details.source[0] !== null) {
      this.line = details.source[0].line;
    }
    if (details.column === void 0 && details.source[0] !== null) {
      this.column = details.source[0].column;
    }
  }
  /**
   * Constructs a new {@link CommonToken} as a copy of another {@link Token}.
   *
   * If `token` is also a {@link CommonToken} instance, the newly
   * constructed token will share a reference to the {@link #text} field and
   * the {@link Pair} stored in {@link source}. Otherwise, {@link text} will
   * be assigned the result of calling {@link getText}, and {@link source}
   * will be constructed from the result of {@link Token.getTokenSource} and
   * {@link Token#getInputStream}.
   *
   * @param token The token to copy.
   */
  static fromToken(token) {
    const source = [token.tokenSource, token.inputStream];
    return new _CommonToken({
      type: token.type,
      line: token.line,
      tokenIndex: token.tokenIndex,
      column: token.column,
      channel: token.channel,
      start: token.start,
      stop: token.stop,
      text: token.text,
      source
    });
  }
  /**
   * Constructs a new {@link CommonToken} with the specified token type and text.
   *
   * @param type The token type.
   * @param text The text of the token.
   */
  static fromType(type, text) {
    return new _CommonToken({ type, text, source: _CommonToken.EMPTY_SOURCE });
  }
  static fromSource(source, type, channel, start, stop) {
    return new _CommonToken({ type, channel, start, stop, source });
  }
  get tokenSource() {
    return this.source[0];
  }
  get inputStream() {
    return this.source[1];
  }
  set inputStream(input) {
    this.source[1] = input;
  }
  /**
   * Constructs a new {@link CommonToken} as a copy of another {@link Token}.
   *
   * If `oldToken` is also a {@link CommonToken} instance, the newly
   * constructed token will share a reference to the {@link text} field and
   * the {@link Pair} stored in {@link source}. Otherwise, {@link text} will
   * be assigned the result of calling {@link getText}, and {@link source}
   * will be constructed from the result of {@link Token.getTokenSource} and
   * {@link Token.getInputStream}.
   */
  clone() {
    const t = new _CommonToken({
      source: this.source,
      type: this.type,
      channel: this.channel,
      start: this.start,
      stop: this.stop,
      tokenIndex: this.tokenIndex,
      line: this.line,
      column: this.column,
      text: this.#text
    });
    return t;
  }
  toString(recognizer) {
    let channelStr = "";
    if (this.channel > 0) {
      channelStr = ",channel=" + this.channel;
    }
    let text = this.text;
    if (text) {
      text = text.replace(/\n/g, "\\n");
      text = text.replace(/\r/g, "\\r");
      text = text.replace(/\t/g, "\\t");
    } else {
      text = "<no text>";
    }
    let typeString = String(this.type);
    if (recognizer) {
      typeString = recognizer.vocabulary.getDisplayName(this.type) ?? "<unknown>";
    }
    return "[@" + this.tokenIndex + "," + this.start + ":" + this.stop + "='" + text + "',<" + typeString + ">" + channelStr + "," + this.line + ":" + this.column + "]";
  }
  get text() {
    if (this.#text !== void 0) {
      return this.#text;
    }
    const input = this.inputStream;
    if (!input) {
      return void 0;
    }
    const n2 = input.size;
    if (this.start < n2 && this.stop < n2) {
      return input.getTextFromRange(this.start, this.stop);
    }
    return "<EOF>";
  }
  set text(text) {
    this.#text = text;
  }
  // WritableToken implementation
  setText(text) {
    this.#text = text;
  }
  setType(ttype) {
    this.type = ttype;
  }
  setLine(line) {
    this.line = line;
  }
  setCharPositionInLine(pos) {
    this.column = pos;
  }
  setChannel(channel) {
    this.channel = channel;
  }
  setTokenIndex(index) {
    this.tokenIndex = index;
  }
};

// src/tree/Trees.ts
var Trees = class _Trees {
  static {
    __name(this, "Trees");
  }
  /**
   * Print out a whole tree in LISP form. {@link getNodeText} is used on the
   * node payloads to get the text for the nodes.  Detect
   * parse trees and extract data appropriately.
   */
  static toStringTree(tree, ruleNames, recog) {
    ruleNames = ruleNames ?? null;
    if (recog) {
      ruleNames = recog.ruleNames;
    }
    let s = _Trees.getNodeText(tree, ruleNames);
    s = escapeWhitespace(s, false);
    const c = tree.getChildCount();
    if (c === 0) {
      return s;
    }
    let res = "(" + s + " ";
    if (c > 0) {
      s = _Trees.toStringTree(tree.getChild(0), ruleNames);
      res = res.concat(s);
    }
    for (let i = 1; i < c; i++) {
      s = _Trees.toStringTree(tree.getChild(i), ruleNames);
      res = res.concat(" " + s);
    }
    res = res.concat(")");
    return res;
  }
  static getNodeText(t, ruleNames, recog) {
    ruleNames = ruleNames ?? null;
    if (recog) {
      ruleNames = recog.ruleNames;
    }
    if (ruleNames !== null) {
      if (t instanceof ParserRuleContext) {
        const context = t.ruleContext;
        const altNumber = context.getAltNumber();
        if (altNumber !== 0) {
          return ruleNames[t.ruleIndex] + ":" + altNumber;
        }
        return ruleNames[t.ruleIndex];
      } else if (t instanceof ErrorNode) {
        return t.toString();
      } else if (t instanceof TerminalNode) {
        return t.symbol.text;
      }
    }
    const payload = t.getPayload();
    if (isToken(payload)) {
      return payload.text;
    }
    return String(t.getPayload());
  }
  /**
   * Return ordered list of all children of this node
   */
  static getChildren(t) {
    const list = [];
    for (let i = 0; i < t.getChildCount(); i++) {
      list.push(t.getChild(i));
    }
    return list;
  }
  /**
   * Return a list of all ancestors of this node.  The first node of
   * list is the root and the last is the parent of this node.
   */
  static getAncestors(t) {
    if (t.parent === null) {
      return [];
    }
    let ancestors = [];
    let p = t.parent;
    while (p !== null) {
      ancestors = [p].concat(ancestors);
      p = p.parent;
    }
    return ancestors;
  }
  /**
   * Return true if t is u's parent or a node on path to root from u.
   */
  static isAncestorOf(t, u) {
    if (t === null || u === null || t.parent === null) {
      return false;
    }
    let p = u.parent;
    while (p !== null) {
      if (t === p) {
        return true;
      }
      p = p.parent;
    }
    return false;
  }
  static findAllTokenNodes(t, ttype) {
    return _Trees.findAllNodes(t, ttype, true);
  }
  static findAllRuleNodes(t, ruleIndex) {
    return _Trees.findAllNodes(t, ruleIndex, false);
  }
  static findAllNodes(t, index, findTokens) {
    const nodes = [];
    _Trees.doFindAllNodes(t, index, findTokens, nodes);
    return nodes;
  }
  static descendants(t) {
    let nodes = [t];
    for (let i = 0; i < t.getChildCount(); i++) {
      nodes = nodes.concat(_Trees.descendants(t.getChild(i)));
    }
    return nodes;
  }
  /**
   * Find smallest subtree of t enclosing range startTokenIndex..stopTokenIndex
   * inclusively using post order traversal. Recursive depth-first-search.
   */
  static getRootOfSubtreeEnclosingRegion(t, startTokenIndex, stopTokenIndex) {
    const n2 = t.getChildCount();
    for (let i = 0; i < n2; i++) {
      const child = t.getChild(i);
      const r = this.getRootOfSubtreeEnclosingRegion(child, startTokenIndex, stopTokenIndex);
      if (r !== null) {
        return r;
      }
    }
    if (t instanceof ParserRuleContext) {
      if (startTokenIndex >= t.start.tokenIndex && // is range fully contained in t?
      (t.stop === null || stopTokenIndex <= t.stop.tokenIndex)) {
        return t;
      }
    }
    return null;
  }
  /**
   * Replace any subtree siblings of root that are completely to left
   * or right of lookahead range with a CommonToken(Token.INVALID_TYPE,"...")
   * node. The source interval for t is not altered to suit smaller range!
   *
   * WARNING: destructive to t.
   */
  static stripChildrenOutOfRange(t, root, startIndex, stopIndex) {
    if (t === null) {
      return;
    }
    for (let i = 0; i < t.getChildCount(); i++) {
      const child = t.getChild(i);
      const range = child.getSourceInterval();
      if (t instanceof ParserRuleContext && (range.stop < startIndex || range.start > stopIndex)) {
        if (this.isAncestorOf(child, root)) {
          const abbrev = CommonToken.fromType(Token.INVALID_TYPE, "...");
          t.children[i] = new TerminalNode(abbrev);
        }
      }
    }
  }
  static doFindAllNodes(t, index, findTokens, nodes) {
    if (findTokens && t instanceof TerminalNode) {
      if (t.symbol?.type === index) {
        nodes.push(t);
      }
    } else if (!findTokens && t instanceof ParserRuleContext) {
      if (t.ruleIndex === index) {
        nodes.push(t);
      }
    }
    for (let i = 0; i < t.getChildCount(); i++) {
      _Trees.doFindAllNodes(t.getChild(i), index, findTokens, nodes);
    }
  }
};

// src/ParserRuleContext.ts
var ParserRuleContext = class _ParserRuleContext {
  static {
    __name(this, "ParserRuleContext");
  }
  static empty = new _ParserRuleContext(null);
  start = null;
  stop = null;
  children = [];
  /**
   * What state invoked the rule associated with this context?
   *  The "return address" is the followState of invokingState
   *  If parent is null, this should be -1 this context object represents
   *  the start rule.
   */
  invokingState;
  parent;
  /**
   * A rule context is a record of a single rule invocation. It knows
   * which context invoked it, if any. If there is no parent context, then
   * naturally the invoking state is not valid.  The parent link
   * provides a chain upwards from the current rule invocation to the root
   * of the invocation tree, forming a stack. We actually carry no
   * information about the rule associated with this context (except
   * when parsing). We keep only the state number of the invoking state from
   * the ATN submachine that invoked this. Contrast this with the s
   * pointer inside ParserRuleContext that tracks the current state
   * being "executed" for the current rule.
   *
   * The parent contexts are useful for computing lookahead sets and
   * getting error information.
   *
   * These objects are used during parsing and prediction.
   * For the special case of parsers, we use the subclass
   * ParserRuleContext.
   */
  constructor(parent, invokingStateNumber = -1) {
    this.parent = parent;
    this.invokingState = invokingStateNumber;
  }
  /** Copy a context */
  copyFrom(ctx) {
    this.parent = ctx.parent;
    this.invokingState = ctx.invokingState;
    this.children.slice(0, this.children.length);
    this.start = ctx.start;
    this.stop = ctx.stop;
    if (ctx.children) {
      ctx.children.forEach((child) => {
        if (child instanceof ErrorNode) {
          this.children.push(child);
          child.parent = this;
        }
      });
    }
  }
  // Double dispatch methods for listeners
  enterRule(_listener) {
  }
  exitRule(_listener) {
  }
  addChild(child) {
    this.children.push(child);
    return child;
  }
  /**
   * Used by enterOuterAlt to toss out a RuleContext previously added as
   * we entered a rule. If we have label, we will need to remove
   * generic ruleContext object.
   */
  removeLastChild() {
    this.children.pop();
  }
  addTokenNode(token) {
    const node = new TerminalNode(token);
    this.children.push(node);
    node.parent = this;
    return node;
  }
  addErrorNode(errorNode) {
    errorNode.parent = this;
    this.children.push(errorNode);
    return errorNode;
  }
  getChild(i, type) {
    if (i < 0 || i >= this.children.length) {
      return null;
    }
    if (!type) {
      return this.children[i];
    }
    for (const child of this.children) {
      if (child instanceof type) {
        if (i === 0) {
          return child;
        } else {
          i -= 1;
        }
      }
    }
    return null;
  }
  getToken(ttype, i) {
    if (i < 0 || i >= this.children.length) {
      return null;
    }
    for (const child of this.children) {
      if ("symbol" in child) {
        if (child.symbol?.type === ttype) {
          if (i === 0) {
            return child;
          } else {
            i -= 1;
          }
        }
      }
    }
    return null;
  }
  getTokens(ttype) {
    const tokens = [];
    for (const child of this.children) {
      if ("symbol" in child) {
        if (child.symbol?.type === ttype) {
          tokens.push(child);
        }
      }
    }
    return tokens;
  }
  // XXX: base the child type selection on the rule index, not the class.
  getRuleContext(index, ctxType) {
    return this.getChild(index, ctxType);
  }
  // XXX: base the child type selection on the rule index, not the class.
  getRuleContexts(ctxType) {
    const contexts = [];
    for (const child of this.children) {
      if (child instanceof ctxType) {
        contexts.push(child);
      }
    }
    return contexts;
  }
  getChildCount() {
    return this.children.length;
  }
  getSourceInterval() {
    if (this.start === null) {
      return Interval.INVALID_INTERVAL;
    }
    if (this.stop === null || this.stop.tokenIndex < this.start.tokenIndex) {
      return new Interval(this.start.tokenIndex, this.start.tokenIndex - 1);
    }
    return new Interval(this.start.tokenIndex, this.stop.tokenIndex);
  }
  depth() {
    let n2 = 0;
    let p = this;
    while (p !== null) {
      p = p.parent;
      n2 += 1;
    }
    return n2;
  }
  /**
   * A context is empty if there is no invoking state; meaning nobody call
   * current context.
   */
  isEmpty() {
    return this.invokingState === -1;
  }
  get ruleContext() {
    return this;
  }
  get ruleIndex() {
    return -1;
  }
  getPayload() {
    return this;
  }
  getText() {
    if (this.children.length === 0) {
      return "";
    }
    return this.children.map((child) => {
      return child.getText();
    }).join("");
  }
  /**
   * For rule associated with this parse tree internal node, return
   * the outer alternative number used to match the input. Default
   * implementation does not compute nor store this alt num. Create
   * a subclass of ParserRuleContext with backing field and set
   * option contextSuperClass.
   * to set it.
   */
  getAltNumber() {
    return ATN.INVALID_ALT_NUMBER;
  }
  /**
   * Set the outer alternative number for this context node. Default
   * implementation does nothing to avoid backing field overhead for
   * trees that don't need it.  Create
   * a subclass of ParserRuleContext with backing field and set
   * option contextSuperClass.
   */
  setAltNumber(_altNumber) {
  }
  accept(visitor) {
    return visitor.visitChildren(this);
  }
  toStringTree(...args) {
    if (args.length < 2) {
      return Trees.toStringTree(this, null, args[0]);
    }
    return Trees.toStringTree(this, args[0], args[1]);
  }
  toString(ruleNames, stop) {
    ruleNames = ruleNames ?? null;
    stop = stop ?? null;
    let p = this;
    let s = "[";
    while (p !== null && p !== stop) {
      if (ruleNames === null) {
        if (!p.isEmpty()) {
          s += p.invokingState;
        }
      } else {
        const ri = p.ruleIndex;
        const ruleName = ri >= 0 && ri < ruleNames.length ? ruleNames[ri] : "" + ri;
        s += ruleName;
      }
      if (p.parent !== null && (ruleNames !== null || !p.parent.isEmpty())) {
        s += " ";
      }
      p = p.parent;
    }
    s += "]";
    return s;
  }
};

// src/atn/helpers.ts
var createSingletonPredictionContext = /* @__PURE__ */ __name((parent, returnState) => {
  if (returnState === PredictionContext.EMPTY_RETURN_STATE && parent === null) {
    return EmptyPredictionContext.instance;
  } else {
    return new SingletonPredictionContext(parent, returnState);
  }
}, "createSingletonPredictionContext");

// src/atn/PredictionContextUtils.ts
var predictionContextFromRuleContext = /* @__PURE__ */ __name((atn, outerContext) => {
  if (!outerContext) {
    outerContext = ParserRuleContext.empty;
  }
  if (!outerContext.parent || outerContext === ParserRuleContext.empty) {
    return EmptyPredictionContext.instance;
  }
  const parent = predictionContextFromRuleContext(atn, outerContext.parent);
  const state = atn.states[outerContext.invokingState];
  const transition = state.transitions[0];
  return createSingletonPredictionContext(parent, transition.followState.stateNumber);
}, "predictionContextFromRuleContext");

// src/atn/LL1Analyzer.ts
var LL1Analyzer = class _LL1Analyzer {
  constructor(atn) {
    this.atn = atn;
  }
  static {
    __name(this, "LL1Analyzer");
  }
  /**
   * Special value added to the lookahead sets to indicate that we hit
   * a predicate during analysis if `seeThruPreds==false`.
   */
  static hitPredicate = Token.INVALID_TYPE;
  /**
   * Calculates the SLL(1) expected lookahead set for each outgoing transition
   * of an {@link ATNState}. The returned array has one element for each
   * outgoing transition in `s`. If the closure from transition
   * _i_ leads to a semantic predicate before matching a symbol, the
   * element at index *i* of the result will be `undefined`.
   *
   * @param s the ATN state
   * @returns the expected symbols for each outgoing transition of `s`.
   */
  getDecisionLookahead(s) {
    const count = s.transitions.length;
    const look = new Array(count);
    for (let alt = 0; alt < count; alt++) {
      const set = new IntervalSet();
      const lookBusy = new HashSet();
      this.doLook(
        s.transitions[alt].target,
        void 0,
        EmptyPredictionContext.instance,
        set,
        lookBusy,
        new BitSet(),
        false,
        false
      );
      if (set.length > 0 && !set.contains(_LL1Analyzer.hitPredicate)) {
        look[alt] = set;
      }
    }
    return look;
  }
  /**
   * Compute set of tokens that can follow `s` in the ATN in the
   * specified `ctx`.
   *
   * If `ctx` is `null` and the end of the rule containing
   * `s` is reached, {@link Token//EPSILON} is added to the result set.
   * If `ctx` is not `null` and the end of the outermost rule is
   * reached, {@link Token//EOF} is added to the result set.
   *
   * @param s the ATN state
   * @param stopState the ATN state to stop at. This can be a
   * {@link BlockEndState} to detect epsilon paths through a closure.
   * @param ctx the complete parser context, or `null` if the context
   * should be ignored
   *
   * @returns The set of tokens that can follow `s` in the ATN in the
   * specified `ctx`.
   */
  look(s, stopState, ctx) {
    const r = new IntervalSet();
    const lookContext = ctx ? predictionContextFromRuleContext(this.atn, ctx) : null;
    this.doLook(s, stopState, lookContext, r, new HashSet(), new BitSet(), true, true);
    return r;
  }
  /**
   * Compute set of tokens that can follow `s` in the ATN in the
   * specified `ctx`.
   *
   * If `ctx` is `null` and `stopState` or the end of the
   * rule containing `s` is reached, {@link Token//EPSILON} is added to
   * the result set. If `ctx` is not `null` and `addEOF` is
   * `true` and `stopState` or the end of the outermost rule is
   * reached, {@link Token//EOF} is added to the result set.
   *
   * @param s the ATN state.
   * @param stopState the ATN state to stop at. This can be a
   * {@link BlockEndState} to detect epsilon paths through a closure.
   * @param ctx The outer context, or `null` if the outer context should
   * not be used.
   * @param look The result lookahead set.
   * @param lookBusy A set used for preventing epsilon closures in the ATN
   * from causing a stack overflow. Outside code should pass
   * `new CustomizedSet<ATNConfig>` for this argument.
   * @param calledRuleStack A set used for preventing left recursion in the
   * ATN from causing a stack overflow. Outside code should pass
   * `new BitSet()` for this argument.
   * @param seeThruPreds `true` to true semantic predicates as
   * implicitly `true` and "see through them", otherwise `false`
   * to treat semantic predicates as opaque and add {@link hitPredicate} to the
   * result if one is encountered.
   * @param addEOF Add {@link Token//EOF} to the result if the end of the
   * outermost context is reached. This parameter has no effect if `ctx`
   * is `null`.
   */
  doLook(s, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF) {
    const c = ATNConfig.createWithContext(s, 0, ctx);
    if (lookBusy.get(c)) {
      return;
    }
    lookBusy.add(c);
    if (s === stopState) {
      if (!ctx) {
        look.addOne(Token.EPSILON);
        return;
      } else if (ctx.isEmpty() && addEOF) {
        look.addOne(Token.EOF);
        return;
      }
    }
    if (s.constructor.stateType === ATNState.RULE_STOP) {
      if (!ctx) {
        look.addOne(Token.EPSILON);
        return;
      } else if (ctx.isEmpty() && addEOF) {
        look.addOne(Token.EOF);
        return;
      }
      if (ctx !== EmptyPredictionContext.instance) {
        const removed = calledRuleStack.get(s.ruleIndex);
        try {
          calledRuleStack.clear(s.ruleIndex);
          for (let i = 0; i < ctx.length; i++) {
            const returnState = this.atn.states[ctx.getReturnState(i)];
            this.doLook(
              returnState,
              stopState,
              ctx.getParent(i),
              look,
              lookBusy,
              calledRuleStack,
              seeThruPreds,
              addEOF
            );
          }
        } finally {
          if (removed) {
            calledRuleStack.set(s.ruleIndex);
          }
        }
        return;
      }
    }
    for (const t of s.transitions) {
      switch (t.transitionType) {
        case Transition.RULE: {
          if (calledRuleStack.get(t.target.ruleIndex)) {
            continue;
          }
          const newContext = createSingletonPredictionContext(
            ctx ?? void 0,
            t.followState.stateNumber
          );
          try {
            calledRuleStack.set(t.target.ruleIndex);
            this.doLook(
              t.target,
              stopState,
              newContext,
              look,
              lookBusy,
              calledRuleStack,
              seeThruPreds,
              addEOF
            );
          } finally {
            calledRuleStack.clear(t.target.ruleIndex);
          }
          break;
        }
        case Transition.PREDICATE:
        case Transition.PRECEDENCE: {
          if (seeThruPreds) {
            this.doLook(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
          } else {
            look.addOne(_LL1Analyzer.hitPredicate);
          }
          break;
        }
        case Transition.WILDCARD: {
          look.addRange(Token.MIN_USER_TOKEN_TYPE, this.atn.maxTokenType);
          break;
        }
        default: {
          if (t.isEpsilon) {
            this.doLook(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
          } else {
            let set = t.label;
            if (set) {
              if (t instanceof NotSetTransition) {
                set = set.complement(Token.MIN_USER_TOKEN_TYPE, this.atn.maxTokenType);
              }
              look.addSet(set);
            }
          }
          break;
        }
      }
    }
  }
};

// src/atn/ATN.ts
var ATN = class {
  static {
    __name(this, "ATN");
  }
  static INVALID_ALT_NUMBER = 0;
  /** Represents the type of recognizer an ATN applies to */
  static LEXER = 0;
  static PARSER = 1;
  /**
   * Used for runtime deserialization of ATNs from strings
   * The type of the ATN.
   */
  grammarType;
  /** The maximum value for any symbol recognized by a transition in the ATN. */
  maxTokenType;
  states = [];
  /**
   * Each subrule/rule is a decision point and we must track them so we
   * can go back later and build DFA predictors for them.  This includes
   * all the rules, subrules, optional blocks, ()+, ()* etc...
   */
  decisionToState = [];
  /** Maps from rule index to starting state number. */
  ruleToStartState = [];
  // Initialized by the ATN deserializer.
  /** Maps from rule index to stop state number. */
  ruleToStopState = [];
  // Initialized by the ATN deserializer.
  modeNameToStartState = /* @__PURE__ */ new Map();
  /**
   * For lexer ATNs, this maps the rule index to the resulting token type.
   * For parser ATNs, this maps the rule index to the generated bypass token
   * type if the {@link ATNDeserializationOptions//isGenerateRuleBypassTransitions}
   * deserialization option was specified; otherwise, this is `null`
   */
  ruleToTokenType = [];
  // Initialized by the ATN deserializer.
  /**
   * For lexer ATNs, this is an array of {@link LexerAction} objects which may
   * be referenced by action transitions in the ATN
   */
  lexerActions = [];
  modeToStartState = [];
  analyzer;
  constructor(grammarType, maxTokenType) {
    this.grammarType = grammarType;
    this.maxTokenType = maxTokenType;
    this.analyzer = new LL1Analyzer(this);
  }
  /**
   * Compute the set of valid tokens that can occur starting in state `s`.
   * If `ctx` is null, the set of tokens will not include what can follow
   * the rule surrounding `s`. In other words, the set will be
   * restricted to tokens reachable staying within `s`'s rule.
   */
  nextTokens(atnState, ctx) {
    if (!ctx && atnState.nextTokenWithinRule) {
      return atnState.nextTokenWithinRule;
    }
    const next = this.analyzer.look(atnState, void 0, ctx);
    if (!ctx) {
      atnState.nextTokenWithinRule = next;
    }
    return next;
  }
  addState(state) {
    if (state) {
      state.stateNumber = this.states.length;
    }
    this.states.push(state);
  }
  removeState(state) {
    this.states[state.stateNumber] = null;
  }
  defineDecisionState(s) {
    this.decisionToState.push(s);
    s.decision = this.decisionToState.length - 1;
    return s.decision;
  }
  getDecisionState(decision) {
    if (this.decisionToState.length === 0) {
      return null;
    } else {
      return this.decisionToState[decision];
    }
  }
  getNumberOfDecisions() {
    return this.decisionToState.length;
  }
  /**
   * Computes the set of input symbols which could follow ATN state number
   * `stateNumber` in the specified full `context`. This method
   * considers the complete parser context, but does not evaluate semantic
   * predicates (i.e. all predicates encountered during the calculation are
   * assumed true). If a path in the ATN exists from the starting state to the
   * {@link RuleStopState} of the outermost context without matching any
   * symbols, {@link Token//EOF} is added to the returned set.
   *
   * If `context` is `null`, it is treated as
   * {@link ParserRuleContext//EMPTY}.
   *
   * @param stateNumber the ATN state number
   * @param context the full parse context
   *
   * @returns {IntervalSet} The set of potentially valid input symbols which could follow the
   * specified state in the specified context.
   *
   * @throws IllegalArgumentException if the ATN does not contain a state with
   * number `stateNumber`
   */
  getExpectedTokens(stateNumber, context) {
    if (stateNumber < 0 || stateNumber >= this.states.length) {
      throw new Error("Invalid state number.");
    }
    const s = this.states[stateNumber];
    let following = this.nextTokens(s);
    if (!following.contains(Token.EPSILON)) {
      return following;
    }
    let ctx = context;
    const expected = new IntervalSet();
    expected.addSet(following);
    expected.removeOne(Token.EPSILON);
    while (ctx !== null && ctx.invokingState >= 0 && following.contains(Token.EPSILON)) {
      const invokingState = this.states[ctx.invokingState];
      const rt = invokingState.transitions[0];
      following = this.nextTokens(rt.followState);
      expected.addSet(following);
      expected.removeOne(Token.EPSILON);
      ctx = ctx.parent;
    }
    if (following.contains(Token.EPSILON)) {
      expected.addOne(Token.EOF);
    }
    return expected;
  }
};

// src/atn/BasicState.ts
var BasicState = class extends ATNState {
  static {
    __name(this, "BasicState");
  }
  static stateType = ATNState.BASIC;
};

// src/atn/DecisionState.ts
var DecisionState = class extends ATNState {
  static {
    __name(this, "DecisionState");
  }
  decision = -1;
  nonGreedy = false;
};

// src/atn/BlockStartState.ts
var BlockStartState = class extends DecisionState {
  static {
    __name(this, "BlockStartState");
  }
  endState;
};

// src/atn/BlockEndState.ts
var BlockEndState = class extends ATNState {
  static {
    __name(this, "BlockEndState");
  }
  static stateType = ATNState.BLOCK_END;
  startState;
};

// src/atn/LoopEndState.ts
var LoopEndState = class extends ATNState {
  static {
    __name(this, "LoopEndState");
  }
  static stateType = ATNState.LOOP_END;
  loopBackState;
};

// src/atn/RuleStartState.ts
var RuleStartState = class extends ATNState {
  static {
    __name(this, "RuleStartState");
  }
  static stateType = ATNState.RULE_START;
  stopState;
  isLeftRecursiveRule = false;
};

// src/atn/RuleStopState.ts
var RuleStopState = class extends ATNState {
  static {
    __name(this, "RuleStopState");
  }
  static stateType = ATNState.RULE_STOP;
};

// src/atn/TokensStartState.ts
var TokensStartState = class extends DecisionState {
  static {
    __name(this, "TokensStartState");
  }
  static stateType = ATNState.TOKEN_START;
};

// src/atn/PlusLoopbackState.ts
var PlusLoopbackState = class extends DecisionState {
  static {
    __name(this, "PlusLoopbackState");
  }
  static stateType = ATNState.PLUS_LOOP_BACK;
};

// src/atn/StarLoopbackState.ts
var StarLoopbackState = class extends ATNState {
  static {
    __name(this, "StarLoopbackState");
  }
  static stateType = ATNState.STAR_LOOP_BACK;
};

// src/atn/StarLoopEntryState.ts
var StarLoopEntryState = class extends DecisionState {
  static {
    __name(this, "StarLoopEntryState");
  }
  static stateType = ATNState.STAR_LOOP_ENTRY;
  // This is always set during ATN deserialization
  loopBackState;
  /**
   * Indicates whether this state can benefit from a precedence DFA during SLL
   * decision making.
   *
   * This is a computed property that is calculated during ATN deserialization
   * and stored for use in {@link ParserATNSimulator} and
   * {@link ParserInterpreter}.
   *
   * @see `DFA.isPrecedenceDfa`
   */
  precedenceRuleDecision = false;
};

// src/atn/PlusBlockStartState.ts
var PlusBlockStartState = class extends BlockStartState {
  static {
    __name(this, "PlusBlockStartState");
  }
  static stateType = ATNState.PLUS_BLOCK_START;
  loopBackState;
};

// src/atn/StarBlockStartState.ts
var StarBlockStartState = class extends BlockStartState {
  static {
    __name(this, "StarBlockStartState");
  }
  static stateType = ATNState.STAR_BLOCK_START;
};

// src/atn/BasicBlockStartState.ts
var BasicBlockStartState = class extends BlockStartState {
  static {
    __name(this, "BasicBlockStartState");
  }
  static stateType = ATNState.BLOCK_START;
};

// src/atn/AtomTransition.ts
var AtomTransition = class extends Transition {
  static {
    __name(this, "AtomTransition");
  }
  /** The token type or character value; or, signifies special label. */
  labelValue;
  #label;
  constructor(target, label) {
    super(target);
    this.labelValue = label;
    this.#label = IntervalSet.of(label, label);
  }
  get label() {
    return this.#label;
  }
  get transitionType() {
    return Transition.ATOM;
  }
  matches(symbol) {
    return this.labelValue === symbol;
  }
  toString() {
    return this.labelValue.toString();
  }
};

// src/atn/RuleTransition.ts
var RuleTransition = class extends Transition {
  static {
    __name(this, "RuleTransition");
  }
  ruleIndex;
  precedence;
  followState;
  constructor(ruleStart, ruleIndex, precedence, followState) {
    super(ruleStart);
    this.ruleIndex = ruleIndex;
    this.precedence = precedence;
    this.followState = followState;
  }
  get isEpsilon() {
    return true;
  }
  get transitionType() {
    return Transition.RULE;
  }
  matches(_symbol, _minVocabSymbol, _maxVocabSymbol) {
    return false;
  }
};

// src/atn/RangeTransition.ts
var RangeTransition = class extends Transition {
  static {
    __name(this, "RangeTransition");
  }
  start;
  stop;
  #label = new IntervalSet();
  constructor(target, start, stop) {
    super(target);
    this.start = start;
    this.stop = stop;
    this.#label.addRange(start, stop);
  }
  get label() {
    return this.#label;
  }
  get transitionType() {
    return Transition.RANGE;
  }
  matches(symbol, _minVocabSymbol, _maxVocabSymbol) {
    return symbol >= this.start && symbol <= this.stop;
  }
  toString() {
    return "'" + String.fromCharCode(this.start) + "'..'" + String.fromCharCode(this.stop) + "'";
  }
};

// src/atn/ActionTransition.ts
var ActionTransition = class extends Transition {
  static {
    __name(this, "ActionTransition");
  }
  ruleIndex;
  actionIndex;
  isCtxDependent;
  constructor(target, ruleIndex, actionIndex, isCtxDependent) {
    super(target);
    this.ruleIndex = ruleIndex;
    this.actionIndex = actionIndex ?? -1;
    this.isCtxDependent = isCtxDependent ?? false;
  }
  get isEpsilon() {
    return true;
  }
  get transitionType() {
    return Transition.ACTION;
  }
  matches(_symbol, _minVocabSymbol, _maxVocabSymbol) {
    return false;
  }
  toString() {
    return "action_" + this.ruleIndex + ":" + this.actionIndex;
  }
};

// src/atn/EpsilonTransition.ts
var EpsilonTransition = class extends Transition {
  static {
    __name(this, "EpsilonTransition");
  }
  #outermostPrecedenceReturn;
  constructor(target, outermostPrecedenceReturn = -1) {
    super(target);
    this.#outermostPrecedenceReturn = outermostPrecedenceReturn;
  }
  /**
   * @returns the rule index of a precedence rule for which this transition is
   * returning from, where the precedence value is 0; otherwise, -1.
   *
   * @see ATNConfig.isPrecedenceFilterSuppressed()
   * @see ParserATNSimulator.applyPrecedenceFilter(ATNConfigSet)
   * @since 4.4.1
   */
  get outermostPrecedenceReturn() {
    return this.#outermostPrecedenceReturn;
  }
  get isEpsilon() {
    return true;
  }
  get transitionType() {
    return Transition.EPSILON;
  }
  matches() {
    return false;
  }
  toString() {
    return "epsilon";
  }
};

// src/atn/WildcardTransition.ts
var WildcardTransition = class extends Transition {
  static {
    __name(this, "WildcardTransition");
  }
  get transitionType() {
    return Transition.WILDCARD;
  }
  matches(symbol, minVocabSymbol, maxVocabSymbol) {
    return symbol >= minVocabSymbol && symbol <= maxVocabSymbol;
  }
  toString() {
    return ".";
  }
};

// src/atn/AbstractPredicateTransition.ts
var AbstractPredicateTransition = class extends Transition {
  static {
    __name(this, "AbstractPredicateTransition");
  }
  constructor(target) {
    super(target);
  }
};

// src/atn/PredicateTransition.ts
var PredicateTransition = class extends AbstractPredicateTransition {
  static {
    __name(this, "PredicateTransition");
  }
  ruleIndex;
  predIndex;
  isCtxDependent;
  // e.g., $i ref in pred
  constructor(target, ruleIndex, predIndex, isCtxDependent) {
    super(target);
    this.ruleIndex = ruleIndex;
    this.predIndex = predIndex;
    this.isCtxDependent = isCtxDependent;
  }
  get isEpsilon() {
    return true;
  }
  matches(_symbol, _minVocabSymbol, _maxVocabSymbol) {
    return false;
  }
  get transitionType() {
    return Transition.PREDICATE;
  }
  getPredicate() {
    return new SemanticContext.Predicate(this.ruleIndex, this.predIndex, this.isCtxDependent);
  }
  toString() {
    return "pred_" + this.ruleIndex + ":" + this.predIndex;
  }
};

// src/atn/PrecedencePredicateTransition.ts
var PrecedencePredicateTransition = class extends AbstractPredicateTransition {
  static {
    __name(this, "PrecedencePredicateTransition");
  }
  precedence;
  constructor(target, precedence) {
    super(target);
    this.precedence = precedence;
  }
  get isEpsilon() {
    return true;
  }
  matches(_symbol, _minVocabSymbol, _maxVocabSymbol) {
    return false;
  }
  getPredicate() {
    return new SemanticContext.PrecedencePredicate(this.precedence);
  }
  get transitionType() {
    return Transition.PRECEDENCE;
  }
  toString() {
    return this.precedence + " >= _p";
  }
};

// src/atn/LexerActionType.ts
var LexerActionType = {
  /** The type of a {@link LexerChannelAction} action. */
  CHANNEL: 0,
  /** The type of a {@link LexerCustomAction} action */
  CUSTOM: 1,
  /** The type of a {@link LexerModeAction} action. */
  MODE: 2,
  /** The type of a {@link LexerMoreAction} action. */
  MORE: 3,
  /** The type of a {@link LexerPopModeAction} action. */
  POP_MODE: 4,
  /** The type of a {@link LexerPushModeAction} action. */
  PUSH_MODE: 5,
  /** The type of a {@link LexerSkipAction} action. */
  SKIP: 6,
  /** The type of a {@link LexerTypeAction} action. */
  TYPE: 7
};

// src/atn/LexerSkipAction.ts
var LexerSkipAction = class _LexerSkipAction {
  static {
    __name(this, "LexerSkipAction");
  }
  /** Provides a singleton instance of this parameter-less lexer action. */
  static instance = new _LexerSkipAction();
  actionType;
  isPositionDependent = false;
  constructor() {
    this.actionType = LexerActionType.SKIP;
  }
  equals(obj) {
    return obj === this;
  }
  hashCode() {
    return LexerActionType.SKIP;
  }
  execute(lexer) {
    lexer.skip();
  }
  toString() {
    return "skip";
  }
};

// src/atn/LexerChannelAction.ts
var LexerChannelAction = class _LexerChannelAction {
  static {
    __name(this, "LexerChannelAction");
  }
  channel;
  actionType;
  isPositionDependent = false;
  cachedHashCode;
  constructor(channel) {
    this.actionType = LexerActionType.CHANNEL;
    this.channel = channel;
  }
  /**
   * This action is implemented by calling {@link Lexer.setChannel} with the
   * value provided by {@link getChannel}.
   */
  execute(lexer) {
    lexer.channel = this.channel;
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      hash = MurmurHash.update(hash, this.actionType);
      hash = MurmurHash.update(hash, this.channel);
      this.cachedHashCode = MurmurHash.finish(hash, 2);
    }
    return this.cachedHashCode;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _LexerChannelAction)) {
      return false;
    }
    return this.channel === other.channel;
  }
  toString() {
    return "channel(" + this.channel + ")";
  }
};

// src/atn/LexerCustomAction.ts
var LexerCustomAction = class _LexerCustomAction {
  static {
    __name(this, "LexerCustomAction");
  }
  ruleIndex;
  actionIndex;
  actionType;
  isPositionDependent = true;
  cachedHashCode;
  /**
   * Constructs a custom lexer action with the specified rule and action indexes.
   *
   * @param ruleIndex The rule index to use for calls to {@link Recognizer.action}.
   * @param actionIndex The action index to use for calls to {@link Recognizer.action}.
   */
  constructor(ruleIndex, actionIndex) {
    this.actionType = LexerActionType.CUSTOM;
    this.ruleIndex = ruleIndex;
    this.actionIndex = actionIndex;
  }
  /**
   * Custom actions are implemented by calling {@link Lexer.action} with the
   * appropriate rule and action indexes.
   */
  execute(lexer) {
    lexer.action(null, this.ruleIndex, this.actionIndex);
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      hash = MurmurHash.update(hash, this.actionType);
      hash = MurmurHash.update(hash, this.ruleIndex);
      hash = MurmurHash.update(hash, this.actionIndex);
      this.cachedHashCode = MurmurHash.finish(hash, 3);
    }
    return this.cachedHashCode;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _LexerCustomAction)) {
      return false;
    }
    return this.ruleIndex === other.ruleIndex && this.actionIndex === other.actionIndex;
  }
};

// src/atn/LexerMoreAction.ts
var LexerMoreAction = class _LexerMoreAction {
  static {
    __name(this, "LexerMoreAction");
  }
  static instance = new _LexerMoreAction();
  actionType;
  isPositionDependent = false;
  constructor() {
    this.actionType = LexerActionType.MORE;
  }
  equals(obj) {
    return obj === this;
  }
  hashCode() {
    return LexerActionType.MORE;
  }
  /**
   * This action is implemented by calling {@link Lexer.popMode}.
   */
  execute(lexer) {
    lexer.more();
  }
  toString() {
    return "more";
  }
};

// src/atn/LexerTypeAction.ts
var LexerTypeAction = class _LexerTypeAction {
  static {
    __name(this, "LexerTypeAction");
  }
  type;
  actionType;
  isPositionDependent = false;
  cachedHashCode;
  constructor(type) {
    this.actionType = LexerActionType.TYPE;
    this.type = type;
  }
  execute(lexer) {
    lexer.type = this.type;
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      hash = MurmurHash.update(hash, this.actionType);
      hash = MurmurHash.update(hash, this.type);
      this.cachedHashCode = MurmurHash.finish(hash, 2);
    }
    return this.cachedHashCode;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _LexerTypeAction)) {
      return false;
    }
    return this.type === other.type;
  }
  toString() {
    return "type(" + this.type + ")";
  }
};

// src/atn/LexerPushModeAction.ts
var LexerPushModeAction = class _LexerPushModeAction {
  static {
    __name(this, "LexerPushModeAction");
  }
  mode;
  actionType;
  isPositionDependent = false;
  cachedHashCode;
  constructor(mode) {
    this.actionType = LexerActionType.PUSH_MODE;
    this.mode = mode;
  }
  /**
   * This action is implemented by calling {@link Lexer.pushMode} with the
   * value provided by {@link getMode}.
   */
  execute(lexer) {
    lexer.pushMode(this.mode);
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      hash = MurmurHash.update(hash, this.actionType);
      hash = MurmurHash.update(hash, this.mode);
      this.cachedHashCode = MurmurHash.finish(hash, 2);
    }
    return this.cachedHashCode;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _LexerPushModeAction)) {
      return false;
    }
    return this.mode === other.mode;
  }
  toString() {
    return "pushMode(" + this.mode + ")";
  }
};

// src/atn/LexerPopModeAction.ts
var LexerPopModeAction = class _LexerPopModeAction {
  static {
    __name(this, "LexerPopModeAction");
  }
  static instance = new _LexerPopModeAction();
  actionType;
  isPositionDependent = false;
  constructor() {
    this.actionType = LexerActionType.POP_MODE;
  }
  equals(obj) {
    return obj === this;
  }
  hashCode() {
    return LexerActionType.POP_MODE;
  }
  /**
   * This action is implemented by calling {@link Lexer//popMode}.
   */
  execute(lexer) {
    lexer.popMode();
  }
  toString() {
    return "popMode";
  }
};

// src/atn/LexerModeAction.ts
var LexerModeAction = class _LexerModeAction {
  static {
    __name(this, "LexerModeAction");
  }
  mode;
  actionType;
  isPositionDependent = false;
  cachedHashCode;
  constructor(mode) {
    this.actionType = LexerActionType.MODE;
    this.mode = mode;
  }
  /**
   * This action is implemented by calling {@link Lexer.mode} with the
   * value provided by {@link getMode}.
   */
  execute(lexer) {
    lexer.mode = this.mode;
  }
  hashCode() {
    if (this.cachedHashCode === void 0) {
      let hash = MurmurHash.initialize();
      hash = MurmurHash.update(hash, this.actionType);
      hash = MurmurHash.update(hash, this.mode);
      this.cachedHashCode = MurmurHash.finish(hash, 2);
    }
    return this.cachedHashCode;
  }
  equals(other) {
    if (this === other) {
      return true;
    }
    if (!(other instanceof _LexerModeAction)) {
      return false;
    }
    return this.mode === other.mode;
  }
  toString() {
    return "mode(" + this.mode + ")";
  }
};

// src/atn/ATNDeserializer.ts
var ATNDeserializer = class _ATNDeserializer {
  static {
    __name(this, "ATNDeserializer");
  }
  static SERIALIZED_VERSION = 4;
  static stateTypeMapper = /* @__PURE__ */ new Map([
    [ATNState.INVALID_TYPE, void 0],
    [ATNState.BASIC, BasicState],
    [ATNState.RULE_START, RuleStartState],
    [ATNState.BLOCK_START, BasicBlockStartState],
    [ATNState.PLUS_BLOCK_START, PlusBlockStartState],
    [ATNState.STAR_BLOCK_START, StarBlockStartState],
    [ATNState.TOKEN_START, TokensStartState],
    [ATNState.RULE_STOP, RuleStopState],
    [ATNState.BLOCK_END, BlockEndState],
    [ATNState.STAR_LOOP_BACK, StarLoopbackState],
    [ATNState.STAR_LOOP_ENTRY, StarLoopEntryState],
    [ATNState.PLUS_LOOP_BACK, PlusLoopbackState],
    [ATNState.LOOP_END, LoopEndState]
  ]);
  static lexerActionFactoryMapper = /* @__PURE__ */ new Map([
    [LexerActionType.CHANNEL, (data1) => {
      return new LexerChannelAction(data1);
    }],
    [LexerActionType.CUSTOM, (data1, data2) => {
      return new LexerCustomAction(data1, data2);
    }],
    [LexerActionType.MODE, (data1) => {
      return new LexerModeAction(data1);
    }],
    [LexerActionType.MORE, () => {
      return LexerMoreAction.instance;
    }],
    [LexerActionType.POP_MODE, () => {
      return LexerPopModeAction.instance;
    }],
    [LexerActionType.PUSH_MODE, (data1) => {
      return new LexerPushModeAction(data1);
    }],
    [LexerActionType.SKIP, () => {
      return LexerSkipAction.instance;
    }],
    [LexerActionType.TYPE, (data1) => {
      return new LexerTypeAction(data1);
    }]
  ]);
  data = [];
  pos = 0;
  deserializationOptions;
  actionFactories;
  constructor(options) {
    if (!options) {
      options = { readOnly: false, verifyATN: true, generateRuleBypassTransitions: false };
    }
    this.deserializationOptions = options;
  }
  deserialize(data) {
    this.data = data;
    this.checkVersion();
    const atn = this.readATN();
    this.readStates(atn);
    this.readRules(atn);
    this.readModes(atn);
    const sets = [];
    this.readSets(atn, sets);
    this.readEdges(atn, sets);
    this.readDecisions(atn);
    this.readLexerActions(atn);
    this.markPrecedenceDecisions(atn);
    this.verifyATN(atn);
    if (this.deserializationOptions.generateRuleBypassTransitions && atn.grammarType === ATN.PARSER) {
      this.generateRuleBypassTransitions(atn);
      this.verifyATN(atn);
    }
    return atn;
  }
  checkVersion() {
    const version = this.data[this.pos++];
    if (version !== _ATNDeserializer.SERIALIZED_VERSION) {
      throw new Error("Could not deserialize ATN with version " + version + " (expected " + _ATNDeserializer.SERIALIZED_VERSION + ").");
    }
  }
  readATN() {
    const grammarType = this.data[this.pos++];
    const maxTokenType = this.data[this.pos++];
    return new ATN(grammarType, maxTokenType);
  }
  readStates(atn) {
    let j;
    let stateNumber;
    const loopBackStateNumbers = [];
    const endStateNumbers = [];
    const stateCount = this.data[this.pos++];
    for (let i = 0; i < stateCount; i++) {
      const stateType = this.data[this.pos++];
      if (stateType === ATNState.INVALID_TYPE) {
        atn.addState(null);
        continue;
      }
      const ruleIndex = this.data[this.pos++];
      const s = this.stateFactory(stateType, ruleIndex);
      if (stateType === ATNState.LOOP_END) {
        const loopBackStateNumber = this.data[this.pos++];
        loopBackStateNumbers.push([s, loopBackStateNumber]);
      } else if (s instanceof BlockStartState) {
        const endStateNumber = this.data[this.pos++];
        endStateNumbers.push([s, endStateNumber]);
      }
      atn.addState(s);
    }
    for (j = 0; j < loopBackStateNumbers.length; j++) {
      const pair = loopBackStateNumbers[j];
      pair[0].loopBackState = atn.states[pair[1]] ?? void 0;
    }
    for (j = 0; j < endStateNumbers.length; j++) {
      const pair = endStateNumbers[j];
      pair[0].endState = atn.states[pair[1]];
    }
    const numNonGreedyStates = this.data[this.pos++];
    for (j = 0; j < numNonGreedyStates; j++) {
      stateNumber = this.data[this.pos++];
      atn.states[stateNumber].nonGreedy = true;
    }
    const numPrecedenceStates = this.data[this.pos++];
    for (j = 0; j < numPrecedenceStates; j++) {
      stateNumber = this.data[this.pos++];
      atn.states[stateNumber].isLeftRecursiveRule = true;
    }
  }
  readRules(atn) {
    let i;
    const ruleCount = this.data[this.pos++];
    if (atn.grammarType === ATN.LEXER) {
      atn.ruleToTokenType = new Array(ruleCount);
      atn.ruleToTokenType.fill(0);
    }
    atn.ruleToStartState = new Array(ruleCount);
    atn.ruleToStartState.fill(null);
    for (i = 0; i < ruleCount; i++) {
      const s = this.data[this.pos++];
      atn.ruleToStartState[i] = atn.states[s];
      if (atn.grammarType === ATN.LEXER) {
        const tokenType = this.data[this.pos++];
        atn.ruleToTokenType[i] = tokenType;
      }
    }
    atn.ruleToStopState = new Array(ruleCount);
    atn.ruleToStopState.fill(null);
    for (i = 0; i < atn.states.length; i++) {
      const state = atn.states[i];
      if (!(state instanceof RuleStopState)) {
        continue;
      }
      atn.ruleToStopState[state.ruleIndex] = state;
      atn.ruleToStartState[state.ruleIndex].stopState = state;
    }
  }
  readModes(atn) {
    const modeCount = this.data[this.pos++];
    for (let i = 0; i < modeCount; i++) {
      const s = this.data[this.pos++];
      atn.modeToStartState.push(atn.states[s]);
    }
  }
  readSets(atn, sets) {
    const m2 = this.data[this.pos++];
    for (let i = 0; i < m2; i++) {
      const intervalSet = new IntervalSet();
      sets.push(intervalSet);
      const n2 = this.data[this.pos++];
      const containsEof = this.data[this.pos++];
      if (containsEof !== 0) {
        intervalSet.addOne(-1);
      }
      for (let j = 0; j < n2; j++) {
        const i1 = this.data[this.pos++];
        const i2 = this.data[this.pos++];
        intervalSet.addRange(i1, i2);
      }
    }
  }
  readEdges(atn, sets) {
    let i;
    let j;
    let state;
    let trans;
    let target;
    const edgeCount = this.data[this.pos++];
    for (i = 0; i < edgeCount; i++) {
      const src = this.data[this.pos++];
      const trg = this.data[this.pos++];
      const ttype = this.data[this.pos++];
      const arg1 = this.data[this.pos++];
      const arg2 = this.data[this.pos++];
      const arg3 = this.data[this.pos++];
      trans = this.edgeFactory(atn, ttype, trg, arg1, arg2, arg3, sets);
      const srcState = atn.states[src];
      srcState.addTransition(trans);
    }
    for (i = 0; i < atn.states.length; i++) {
      state = atn.states[i];
      for (j = 0; j < state.transitions.length; j++) {
        const t = state.transitions[j];
        if (!(t instanceof RuleTransition)) {
          continue;
        }
        let outermostPrecedenceReturn = -1;
        if (atn.ruleToStartState[t.target.ruleIndex].isLeftRecursiveRule) {
          if (t.precedence === 0) {
            outermostPrecedenceReturn = t.target.ruleIndex;
          }
        }
        trans = new EpsilonTransition(t.followState, outermostPrecedenceReturn);
        atn.ruleToStopState[t.target.ruleIndex].addTransition(trans);
      }
    }
    for (i = 0; i < atn.states.length; i++) {
      state = atn.states[i];
      if (state instanceof BlockStartState) {
        if (!state.endState) {
          throw new Error("IllegalState");
        }
        if (state.endState.startState) {
          throw new Error("IllegalState");
        }
        state.endState.startState = state;
      }
      if (state instanceof PlusLoopbackState) {
        for (j = 0; j < state.transitions.length; j++) {
          target = state.transitions[j].target;
          if (target instanceof PlusBlockStartState) {
            target.loopBackState = state;
          }
        }
      } else if (state instanceof StarLoopbackState) {
        for (j = 0; j < state.transitions.length; j++) {
          target = state.transitions[j].target;
          if (target instanceof StarLoopEntryState) {
            target.loopBackState = state;
          }
        }
      }
    }
  }
  readDecisions(atn) {
    const decisionCount = this.data[this.pos++];
    for (let i = 0; i < decisionCount; i++) {
      const s = this.data[this.pos++];
      const decState = atn.states[s];
      atn.decisionToState.push(decState);
      decState.decision = i;
    }
  }
  readLexerActions(atn) {
    if (atn.grammarType === ATN.LEXER) {
      const count = this.data[this.pos++];
      atn.lexerActions = [];
      for (let i = 0; i < count; i++) {
        const actionType = this.data[this.pos++];
        const data1 = this.data[this.pos++];
        const data2 = this.data[this.pos++];
        atn.lexerActions.push(this.lexerActionFactory(actionType, data1, data2));
      }
    }
  }
  generateRuleBypassTransitions(atn) {
    let i;
    const count = atn.ruleToStartState.length;
    for (i = 0; i < count; i++) {
      atn.ruleToTokenType[i] = atn.maxTokenType + i + 1;
    }
    for (i = 0; i < count; i++) {
      this.generateRuleBypassTransition(atn, i);
    }
  }
  generateRuleBypassTransition(atn, idx) {
    let i;
    let state;
    const bypassStart = new BasicBlockStartState();
    bypassStart.ruleIndex = idx;
    atn.addState(bypassStart);
    const bypassStop = new BlockEndState();
    bypassStop.ruleIndex = idx;
    atn.addState(bypassStop);
    bypassStart.endState = bypassStop;
    atn.defineDecisionState(bypassStart);
    bypassStop.startState = bypassStart;
    let excludeTransition = null;
    let endState = null;
    if (atn.ruleToStartState[idx].isLeftRecursiveRule) {
      endState = null;
      for (i = 0; i < atn.states.length; i++) {
        state = atn.states[i];
        if (this.stateIsEndStateFor(state, idx)) {
          endState = state;
          excludeTransition = state.loopBackState.transitions[0];
          break;
        }
      }
      if (excludeTransition === null) {
        throw new Error("Couldn't identify final state of the precedence rule prefix section.");
      }
    } else {
      endState = atn.ruleToStopState[idx];
    }
    for (i = 0; i < atn.states.length; i++) {
      state = atn.states[i];
      for (const transition of state.transitions) {
        if (transition === excludeTransition) {
          continue;
        }
        if (transition.target === endState) {
          transition.target = bypassStop;
        }
      }
    }
    const ruleToStartState = atn.ruleToStartState[idx];
    while (ruleToStartState.transitions.length > 0) {
      const transition = ruleToStartState.removeTransition(ruleToStartState.transitions.length - 1);
      bypassStart.addTransition(transition);
    }
    atn.ruleToStartState[idx].addTransition(new EpsilonTransition(bypassStart));
    if (endState) {
      bypassStop.addTransition(new EpsilonTransition(endState));
    }
    const matchState = new BasicState();
    atn.addState(matchState);
    matchState.addTransition(new AtomTransition(bypassStop, atn.ruleToTokenType[idx]));
    bypassStart.addTransition(new EpsilonTransition(matchState));
  }
  stateIsEndStateFor(state, idx) {
    if (state.ruleIndex !== idx) {
      return null;
    }
    if (!(state instanceof StarLoopEntryState)) {
      return null;
    }
    const maybeLoopEndState = state.transitions[state.transitions.length - 1].target;
    if (!(maybeLoopEndState instanceof LoopEndState)) {
      return null;
    }
    if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transitions[0].target instanceof RuleStopState) {
      return state;
    } else {
      return null;
    }
  }
  /**
   * Analyze the {@link StarLoopEntryState} states in the specified ATN to set
   * the {@link StarLoopEntryState} field to the correct value.
   *
   * @param atn The ATN.
   */
  markPrecedenceDecisions(atn) {
    for (const state of atn.states) {
      if (!(state instanceof StarLoopEntryState)) {
        continue;
      }
      if (atn.ruleToStartState[state.ruleIndex].isLeftRecursiveRule) {
        const maybeLoopEndState = state.transitions[state.transitions.length - 1].target;
        if (maybeLoopEndState instanceof LoopEndState) {
          if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.transitions[0].target instanceof RuleStopState) {
            state.precedenceRuleDecision = true;
          }
        }
      }
    }
  }
  verifyATN(atn) {
    if (!this.deserializationOptions.verifyATN) {
      return;
    }
    for (const state of atn.states) {
      if (state === null) {
        continue;
      }
      this.checkCondition(state.epsilonOnlyTransitions || state.transitions.length <= 1);
      if (state instanceof PlusBlockStartState) {
        this.checkCondition(state.loopBackState !== null);
      } else if (state instanceof StarLoopEntryState) {
        this.checkCondition(state.loopBackState !== null);
        this.checkCondition(state.transitions.length === 2);
        if (state.transitions[0].target instanceof StarBlockStartState) {
          this.checkCondition(state.transitions[1].target instanceof LoopEndState);
          this.checkCondition(!state.nonGreedy);
        } else if (state.transitions[0].target instanceof LoopEndState) {
          this.checkCondition(state.transitions[1].target instanceof StarBlockStartState);
          this.checkCondition(state.nonGreedy);
        } else {
          throw new Error("IllegalState");
        }
      } else if (state instanceof StarLoopbackState) {
        this.checkCondition(state.transitions.length === 1);
        this.checkCondition(state.transitions[0].target instanceof StarLoopEntryState);
      } else if (state instanceof LoopEndState) {
        this.checkCondition(state.loopBackState !== null);
      } else if (state instanceof RuleStartState) {
        this.checkCondition(state.stopState !== null);
      } else if (state instanceof BlockStartState) {
        this.checkCondition(state.endState !== null);
      } else if (state instanceof BlockEndState) {
        this.checkCondition(state.startState !== null);
      } else if (state instanceof DecisionState) {
        this.checkCondition(state.transitions.length <= 1 || state.decision >= 0);
      } else {
        this.checkCondition(state.transitions.length <= 1 || state instanceof RuleStopState);
      }
    }
  }
  checkCondition(condition, message) {
    if (!condition) {
      if (message === void 0 || message === null) {
        message = "IllegalState";
      }
      throw message;
    }
  }
  edgeFactory(atn, type, trg, arg1, arg2, arg3, sets) {
    const target = atn.states[trg];
    switch (type) {
      case Transition.EPSILON:
        return new EpsilonTransition(target);
      case Transition.RANGE:
        return arg3 !== 0 ? new RangeTransition(target, Token.EOF, arg2) : new RangeTransition(target, arg1, arg2);
      case Transition.RULE:
        return new RuleTransition(atn.states[arg1], arg2, arg3, target);
      case Transition.PREDICATE:
        return new PredicateTransition(target, arg1, arg2, arg3 !== 0);
      case Transition.PRECEDENCE:
        return new PrecedencePredicateTransition(target, arg1);
      case Transition.ATOM:
        return arg3 !== 0 ? new AtomTransition(target, Token.EOF) : new AtomTransition(target, arg1);
      case Transition.ACTION:
        return new ActionTransition(target, arg1, arg2, arg3 !== 0);
      case Transition.SET:
        return new SetTransition(target, sets[arg1]);
      case Transition.NOT_SET:
        return new NotSetTransition(target, sets[arg1]);
      case Transition.WILDCARD:
        return new WildcardTransition(target);
      default:
        throw new Error("The specified transition type: " + type + " is not valid.");
    }
  }
  stateFactory(type, ruleIndex) {
    const ctor = _ATNDeserializer.stateTypeMapper.get(type);
    if (!ctor) {
      throw new Error("The specified state type " + type + " is not valid.");
    }
    const s = new ctor();
    s.ruleIndex = ruleIndex;
    return s;
  }
  lexerActionFactory(type, data1, data2) {
    const factory = _ATNDeserializer.lexerActionFactoryMapper.get(type);
    if (!factory) {
      throw new Error("The specified lexer action type " + type + " is not valid.");
    }
    return factory(data1, data2);
  }
};

// src/misc/InterpreterDataReader.ts
var InterpreterDataReader = class {
  static {
    __name(this, "InterpreterDataReader");
  }
  /**
   * The structure of the data file is very simple. Everything is line based with empty lines
   * separating the different parts. For lexers the layout is:
   * token literal names:
   * ...
   *
   * token symbolic names:
   * ...
   *
   * rule names:
   * ...
   *
   * channel names:
   * ...
   *
   * mode names:
   * ...
   *
   * atn:
   * a single line with comma separated int values, enclosed in a pair of squared brackets.
   *
   * Data for a parser does not contain channel and mode names.
   */
  static parseInterpreterData(source) {
    const ruleNames = [];
    const channels = [];
    const modes = [];
    const literalNames = [];
    const symbolicNames = [];
    const lines = source.split("\n");
    let index = 0;
    let line = lines[index++];
    if (line !== "token literal names:") {
      throw new Error("Unexpected data entry");
    }
    do {
      line = lines[index++];
      if (line.length === 0) {
        break;
      }
      literalNames.push(line === "null" ? null : line);
    } while (true);
    line = lines[index++];
    if (line !== "token symbolic names:") {
      throw new Error("Unexpected data entry");
    }
    do {
      line = lines[index++];
      if (line.length === 0) {
        break;
      }
      symbolicNames.push(line === "null" ? null : line);
    } while (true);
    line = lines[index++];
    if (line !== "rule names:") {
      throw new Error("Unexpected data entry");
    }
    do {
      line = lines[index++];
      if (line.length === 0) {
        break;
      }
      ruleNames.push(line);
    } while (true);
    line = lines[index++];
    if (line === "channel names:") {
      do {
        line = lines[index++];
        if (line.length === 0) {
          break;
        }
        channels.push(line);
      } while (true);
      line = lines[index++];
      if (line !== "mode names:") {
        throw new Error("Unexpected data entry");
      }
      do {
        line = lines[index++];
        if (line.length === 0) {
          break;
        }
        modes.push(line);
      } while (true);
    }
    line = lines[index++];
    if (line !== "atn:") {
      throw new Error("Unexpected data entry");
    }
    line = lines[index++];
    const elements = line.split(",");
    let value;
    const serializedATN = [];
    for (let i = 0; i < elements.length; ++i) {
      const element = elements[i];
      if (element.startsWith("[")) {
        value = Number(element.substring(1).trim());
      } else if (element.endsWith("]")) {
        value = Number(element.substring(0, element.length - 1).trim());
      } else {
        value = Number(element.trim());
      }
      serializedATN[i] = value;
    }
    const deserializer = new ATNDeserializer();
    return {
      atn: deserializer.deserialize(serializedATN),
      vocabulary: new Vocabulary(literalNames, symbolicNames, []),
      ruleNames,
      channels: channels.length > 0 ? channels : void 0,
      modes: modes.length > 0 ? modes : void 0
    };
  }
};
