public static List parseJqPath()

in processing/src/main/java/org/apache/druid/segment/nested/NestedPathFinder.java [230:328]


  public static List<NestedPathPart> parseJqPath(@Nullable String path)
  {
    if (path == null || path.isEmpty()) {
      return Collections.emptyList();
    }
    List<NestedPathPart> parts = new ArrayList<>();

    if (path.charAt(0) != '.') {
      badFormat(path, "it must start with '.'");
    }

    int partMark = -1;  // position to start the next substring to build the path part
    int dotMark = -1;   // last position where a '.' character was encountered, indicating the start of a new part
    int arrayMark = -1; // position of leading '[' indicating start of array (or field name if '"' immediately follows)
    int quoteMark = -1; // position of leading '"', indicating a quoted field name
    for (int i = 0; i < path.length(); i++) {
      final char current = path.charAt(i);
      if (current == '.' && arrayMark < 0 && quoteMark < 0) {
        if (dotMark >= 0) {
          parts.add(new NestedPathField(getPathSubstring(path, partMark, i)));
        }
        dotMark = i;
        partMark = i + 1;
      } else if (current == '?' && quoteMark < 0) {
        // eat optional marker
        if (partMark != i) {
          if (dotMark >= 0) {
            parts.add(new NestedPathField(getPathSubstring(path, partMark, i)));
            dotMark = -1;
          } else {
            badFormat(path, "found '?' at invalid position [%s]", i);
          }
        }
        partMark = i + 1;
      } else if (current == '[' && arrayMark < 0 && quoteMark < 0) {
        if (dotMark == (i - 1) && dotMark != 0) {
          badFormat(path, "found '[' at invalid position [%s], must not follow '.' or must be contained with '\"'", i);
        }
        if (dotMark >= 0 && i > 1) {
          parts.add(new NestedPathField(getPathSubstring(path, partMark, i)));
          dotMark = -1;
        }
        arrayMark = i;
        partMark = i + 1;
      } else if (current == ']' && arrayMark >= 0 && quoteMark < 0) {
        String maybeNumber = getPathSubstring(path, partMark, i);
        try {
          int index = Integer.parseInt(maybeNumber);
          parts.add(new NestedPathArrayElement(index));
          dotMark = -1;
          arrayMark = -1;
          partMark = i + 1;
        }
        catch (NumberFormatException ignored) {
          badFormat(path, "array specifier [%s] should be a number, it was not.  Use \"\" if this value was meant to be a field name", maybeNumber);
        }
      } else if (dotMark == -1 && arrayMark == -1) {
        badFormat(path, "path parts must be separated with '.'");
      } else if (current == '"' && quoteMark < 0) {
        if (partMark != i) {
          badFormat(path, "found '\"' at invalid position [%s], it must immediately follow '.' or '['", i);
        }
        if (arrayMark > 0 && arrayMark != i - 1) {
          badFormat(path, "'\"' within '[', must be immediately after");
        }
        quoteMark = i;
        partMark = i + 1;
      } else if (current == '"' && quoteMark >= 0 && path.charAt(i - 1) != '\\') {
        parts.add(new NestedPathField(getPathSubstring(path, partMark, i)));
        dotMark = -1;
        quoteMark = -1;
        if (arrayMark > 0) {
          // chomp to next char to eat closing array
          if (++i == path.length()) {
            break;
          }
          if (path.charAt(i) != ']') {
            badFormat(path, "closing '\"' must immediately precede ']'");
          }
          partMark = i + 1;
          arrayMark = -1;
        } else {
          partMark = i + 1;
        }
      }
    }
    // add the last element, this should never be an array because they close themselves
    if (partMark < path.length()) {
      if (quoteMark != -1) {
        badFormat(path, "unterminated '\"'");
      }
      if (arrayMark != -1) {
        badFormat(path, "unterminated '['");
      }
      parts.add(new NestedPathField(path.substring(partMark)));
    }

    return parts;
  }