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);
}
}