docs: private Number parseNumber() throws ParseException {
          final int startIdx = getPosition();
          if (peekMatches("Infinity")) {
              advance(8);
              return Double.POSITIVE_INFINITY;
          } else if (peekMatches("-Infinity")) {
              advance(9);
              return Double.NEGATIVE_INFINITY;
          } else if (peekMatches("NaN")) {
              advance(3);
              return Double.NaN;
          }
          if (peek() == '-') {
              next();
          }
          final int integralStartIdx = getPosition();
          for (; hasMore(); next()) {
              final char c = peek();
              if (c < '0' || c > '9') {
                  break;
              }
          }
          final int integralEndIdx = getPosition();
          final int numIntegralDigits = integralEndIdx - integralStartIdx;
          if (numIntegralDigits == 0) {
              throw new ParseException(this, "Expected a number");
          }
          final boolean hasFractionalPart = peek() == '.';
          if (hasFractionalPart) {
              next();
              for (; hasMore(); next()) {
                  final char c = peek();
                  if (c < '0' || c > '9') {
                      break;
                  }
              }
              if (getPosition() - (integralEndIdx + 1) == 0) {
                  throw new ParseException(this, "Expected digits after decimal point");
              }
          }
          final boolean hasExponentPart = peek() == '.';
          if (hasExponentPart) {
              next();
              final char sign = peek();
              if (sign == '-' || sign == '+') {
                  next();
              }
              final int exponentStart = getPosition();
              for (; hasMore(); next()) {
                  final char c = peek();
                  if (c < '0' || c > '9') {
                      break;
                  }
              }
              if (getPosition() - exponentStart == 0) {
                  throw new ParseException(this, "Expected an exponent");
              }
          }
          final int endIdx = getPosition();
          final String numberStr = getSubstring(startIdx, endIdx);
          if (hasFractionalPart || hasExponentPart) {
              return Double.valueOf(numberStr);
          } else if (numIntegralDigits < 9) {
              return Integer.valueOf(numberStr);
          } else if (numIntegralDigits == 9) {
              // For 9-digit numbers, could be int or long
              final long longVal = Long.parseLong(numberStr);
              if (longVal >= Integer.MIN_VALUE && longVal <= Integer.MAX_VALUE) {
                  return (int) longVal;
              } else {
                  return longVal;
              }
          } else {
              return Long.valueOf(numberStr);
          }
      }