public String nextCommand()

in core/src/main/java/com/jetbrains/youtrackdb/internal/common/console/ConsoleCommandStream.java [130:301]


  public String nextCommand() {
    try {
      state = State.TEXT;
      final var result = new StringBuilder();

      while (true) {
        var c = nextCharacter();
        var symbol = symbol(c);

        switch (state) {
          case TEXT:
            switch (symbol) {
              case LETTER:
                result.append(c);
                break;
              case DOUBLE_QUOTE:
                result.append(c);
                state = State.DOUBLE_QUOTE_STRING;
                break;
              case SINGLE_QUOTE:
                result.append(c);
                state = State.SINGLE_QUOTE_STRING;
                break;
              case LEFT_BRACKET:
                result.append(c);
                nestingLevel++;
                break;
              case RIGHT_BRAKET:
                result.append(c);
                nestingLevel--;
                if (nestingLevel <= 0 && isControlBlock(result)) {
                  return result.toString().trim();
                }
                break;
              case HYPHEN:
                if (result.toString().trim().length() == 0) {
                  // allow commands only at the beginning of a row
                  state = State.HYPHEN;
                } else {
                  result.append("-");
                }
                break;
              case POUND:
                if (result.toString().trim().length() == 0) {
                  // otherwise it could just be a RID
                  state = State.SINGLE_LINE_COMMENT;
                } else {
                  result.append("#");
                }
                break;
              case SLASH:
                state = State.SLASH;
                break;
              case STRING_ESCAPE:
              case ASTERISK:
                result.append(c);
                break;
              case SEPARATOR:
              case NEW_LINE:
                if (nestingLevel <= 0) {
                  state = State.TEXT;
                  return result.toString().trim();
                } else {
                  result.append("\n");
                }
                break;
              case EOF:
                state = State.TEXT;
                return result.toString().trim();
            }
            break;

          case SINGLE_QUOTE_STRING:
            if (symbol == Symbol.EOF) {
              return result.toString().trim();
            }
            if (symbol == Symbol.STRING_ESCAPE) {
              state = State.ESCAPING_IN_SINGLE_QUOTE_STRING;
              break;
            }
            if (symbol == Symbol.SINGLE_QUOTE) {
              state = State.TEXT;
            }
            result.append(c);
            break;
          case DOUBLE_QUOTE_STRING:
            if (symbol == Symbol.EOF) {
              return result.toString().trim();
            }
            if (symbol == Symbol.STRING_ESCAPE) {
              state = State.ESCAPING_IN_DOUBLE_QUOTE_STRING;
              break;
            }
            if (symbol == Symbol.DOUBLE_QUOTE) {
              state = State.TEXT;
            }
            result.append(c);
            break;
          case SINGLE_LINE_COMMENT:
            if (symbol == Symbol.NEW_LINE || symbol == Symbol.EOF) {
              state = State.TEXT;
              return result.toString();
            }
            break;
          case MULTI_LINE_COMMENT:
            if (symbol == Symbol.EOF) {
              return result.toString();
            }
            if (symbol == Symbol.ASTERISK) {
              state = State.CLOSING_ASTERISK;
            }
            break;
          case HYPHEN: // found a hyphen, if there is another one, it's a comment
            if (symbol == Symbol.EOF) {
              state = State.TEXT;
              result.append("-");
              return result.toString().trim();
            }
            if (symbol == Symbol.HYPHEN) {
              state = State.SINGLE_LINE_COMMENT;
            } else {
              result.append("-");
              result.append(c);
              state = State.TEXT;
            }
            break;
          case SLASH: // found a slash, if there is an asterisk it is a multi-line comment
            if (symbol == Symbol.EOF) {
              result.append("/");
              return result.toString().trim();
            }
            if (symbol == Symbol.ASTERISK) {
              state = State.MULTI_LINE_COMMENT;
            } else {
              state = State.TEXT;
              result.append("/");
              result.append(c);
            }
            break;
          case CLOSING_ASTERISK: // you are in a multi-line comment and found an asterisk, if there
            // is a slash it's closing the comment
            if (symbol == Symbol.EOF) {
              return result.toString().trim();
            }
            if (symbol == Symbol.SLASH) {
              state = State.TEXT;
            }
            break;
          case ESCAPING_IN_SINGLE_QUOTE_STRING:
            if (symbol == Symbol.EOF) {
              result.append('\\');
              return result.toString().trim();
            }
            result.append('\\');
            result.append(c);
            state = State.SINGLE_QUOTE_STRING;
            break;
          case ESCAPING_IN_DOUBLE_QUOTE_STRING:
            if (symbol == Symbol.EOF) {
              result.append('\\');
              return result.toString().trim();
            }
            result.append('\\');
            result.append(c);
            state = State.DOUBLE_QUOTE_STRING;
            break;
        }
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }