in base/src/com/google/idea/blaze/base/lang/buildfile/lexer/BuildLexerBase.java [279:400]
private void escapedStringLiteral(char quot, boolean isRaw) {
int oldPos = isRaw ? pos - 2 : pos - 1;
boolean inTripleQuote = skipTripleQuote(quot);
// more expensive second choice that expands escaped into a buffer
StringBuilder literal = new StringBuilder();
while (pos < buffer.length) {
char c = buffer[pos];
pos++;
switch (c) {
case '\n':
if (inTripleQuote) {
literal.append(c);
break;
} else {
error("unterminated string literal at eol", oldPos, pos);
addToken(TokenKind.STRING, oldPos, pos - 1, literal.toString());
newline();
return;
}
case '\\':
if (pos == buffer.length) {
error("unterminated string literal at eof", oldPos, pos);
addToken(TokenKind.STRING, oldPos, pos - 1, literal.toString());
return;
}
if (isRaw) {
// Insert \ and the following character.
// As in Python, it means that a raw string can never end with a single \.
literal.append('\\');
literal.append(buffer[pos]);
pos++;
break;
}
c = buffer[pos];
pos++;
switch (c) {
case '\n':
// ignore end of line character
break;
case 'n':
literal.append('\n');
break;
case 'r':
literal.append('\r');
break;
case 't':
literal.append('\t');
break;
case '\\':
literal.append('\\');
break;
case '\'':
literal.append('\'');
break;
case '"':
literal.append('"');
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
{ // octal escape
int octal = c - '0';
if (pos < buffer.length) {
c = buffer[pos];
if (c >= '0' && c <= '7') {
pos++;
octal = (octal << 3) | (c - '0');
if (pos < buffer.length) {
c = buffer[pos];
if (c >= '0' && c <= '7') {
pos++;
octal = (octal << 3) | (c - '0');
}
}
}
}
literal.append((char) (octal & 0xff));
break;
}
case 'a':
case 'b':
case 'f':
case 'N':
case 'u':
case 'U':
case 'v':
case 'x':
// exists in Python but not implemented in Blaze => error
error("escape sequence not implemented: \\" + c, oldPos, pos);
break;
default:
// unknown char escape => "\literal"
literal.append('\\');
literal.append(c);
break;
}
break;
case '\'':
case '"':
if (c != quot || (inTripleQuote && !skipTripleQuote(quot))) {
// Non-matching quote, treat it like a regular char.
literal.append(c);
} else {
// Matching close-delimiter, all done.
addToken(TokenKind.STRING, oldPos, pos, literal.toString());
return;
}
break;
default:
literal.append(c);
break;
}
}
error("unterminated string literal at eof", oldPos, pos);
addToken(TokenKind.STRING, oldPos, pos, literal.toString());
}