protected String parserNextWord()

in core/src/main/java/com/jetbrains/youtrackdb/internal/common/parser/BaseParser.java [558:723]


  protected String parserNextWord(
      final boolean iForceUpperCase, final String iSeparatorChars, boolean preserveEscapes) {
    parserPreviousPos = parserCurrentPos;
    parserLastWord.setLength(0);
    parserEscapeSequenceCount = 0;

    parserSkipWhiteSpaces();
    if (parserCurrentPos == -1) {
      return null;
    }

    var stringBeginChar = ' ';

    final var text2Use = iForceUpperCase ? parserTextUpperCase : parserText;

    while (parserCurrentPos < text2Use.length()) {
      final var c = text2Use.charAt(parserCurrentPos);
      var found = false;
      for (var sepIndex = 0; sepIndex < iSeparatorChars.length(); ++sepIndex) {
        if (iSeparatorChars.charAt(sepIndex) == c) {
          // SEPARATOR AT THE BEGINNING: JUMP IT
          found = true;
          break;
        }
      }
      if (!found) {
        break;
      }

      parserCurrentPos++;
    }

    try {
      var openParenthesis = 0;
      var openBracket = 0;
      var openGraph = 0;

      var escapePos = -1;

      for (; parserCurrentPos < text2Use.length(); parserCurrentPos++) {
        final var c = text2Use.charAt(parserCurrentPos);

        if (escapePos == -1 && c == '\\' && ((parserCurrentPos + 1) < text2Use.length())) {
          // ESCAPE CHARS

          if (openGraph == 0) {
            final var nextChar = text2Use.charAt(parserCurrentPos + 1);
            if (preserveEscapes) {
              parserLastWord.append(c);
              parserLastWord.append(nextChar);
              parserCurrentPos++;
            } else {

              if (nextChar == 'u') {
                parserCurrentPos =
                    StringParser.readUnicode(text2Use, parserCurrentPos + 2, parserLastWord);
                parserEscapeSequenceCount += 5;
              } else {
                if (nextChar == 'n') {
                  parserLastWord.append('\n');
                } else if (nextChar == 'r') {
                  parserLastWord.append('\r');
                } else if (nextChar == 't') {
                  parserLastWord.append('\t');
                } else if (nextChar == 'b') {
                  parserLastWord.append('\b');
                } else if (nextChar == 'f') {
                  parserLastWord.append('\f');
                } else {
                  parserLastWord.append(nextChar);
                  parserEscapeSequenceCount++;
                }

                parserCurrentPos++;
              }
            }
            continue;
          } else {
            escapePos = parserCurrentPos;
          }
        }

        if (escapePos == -1 && (c == '\'' || c == '"')) {
          if (stringBeginChar != ' ') {
            // CLOSE THE STRING?
            if (stringBeginChar == c) {
              // SAME CHAR AS THE BEGIN OF THE STRING: CLOSE IT AND PUSH
              stringBeginChar = ' ';

              if (openBracket == 0 && openGraph == 0 && openParenthesis == 0) {
                parserCurrentPos++;
                parserLastWord.append(c);
                break;
              }
            }
          } else
          // START STRING
          {
            stringBeginChar = c;
          }
        }

        if (stringBeginChar == ' ') {
          if (openBracket == 0
              && openGraph == 0
              && openParenthesis == 0
              && parserCheckSeparator(c, iSeparatorChars)) {
            // SEPARATOR FOUND!
            break;
          } else if (c == '(') {
            openParenthesis++;
          } else if (c == ')' && openParenthesis > 0) {
            openParenthesis--;
          } else if (c == '[') {
            openBracket++;
          } else if (c == ']' && openBracket > 0) {
            openBracket--;
          } else if (c == '{') {
            openGraph++;
          } else if (c == '}' && openGraph > 0) {
            openGraph--;
          }
        }

        if (escapePos != -1) {
          parserEscapeSequenceCount++;
        }

        if (escapePos != parserCurrentPos) {
          escapePos = -1;
        }

        parserLastWord.append(c);
      }

      // CHECK MISSING CHARACTER
      if (stringBeginChar != ' ') {
        throw new IllegalStateException(
            "Missing closed string character: '"
                + stringBeginChar
                + "', position: "
                + parserCurrentPos);
      }
      if (openBracket > 0) {
        throw new IllegalStateException(
            "Missing closed braket character: ']', position: " + parserCurrentPos);
      }
      if (openGraph > 0) {
        throw new IllegalStateException(
            "Missing closed graph character: '}', position: " + parserCurrentPos);
      }
      if (openParenthesis > 0) {
        throw new IllegalStateException(
            "Missing closed parenthesis character: ')', position: " + parserCurrentPos);
      }

    } finally {
      if (parserCurrentPos >= text2Use.length()) {
        // END OF TEXT
        parserCurrentPos = -1;
        parserLastSeparator = ' ';
      }
    }

    return parserLastWord.toString();
  }