Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiline strings #61

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ IDENT
: (ALPHA | UNDERSCORE) (ALPHA | DIGIT | UNDERSCORE)*
;
STRING_VALUE
: BACKTICK_STRING
| TRIPLE_DOUBLE_QUOTE_STRING
;
STRING_NAME
: DOUBLE_QUOTE_STRING
| SINGLE_QUOTE_STRING
;
Expand All @@ -202,6 +206,17 @@ fragment DOUBLE_QUOTE_STRING
fragment SINGLE_QUOTE_STRING
: '\'' ( ESC_SEQ | ~('\\' | '\'' | '\r' | '\n') )* '\''
;
fragment BACKTICK_STRING
: '`' ( ESC_SEQ | ~('\\' | '`') )* '`'
;
fragment TRIPLE_DOUBLE_QUOTE_STRING
: '"""' TDQ_STRING_CHAR*? '"""'
;
fragment TDQ_STRING_CHAR
: ~["\\]
| '"' { !(_input.LA(1) == '"' && _input.LA(2) == '"') }?
| ESC_SEQ
;
fragment EXPONENT
: (FLOAT_LIT|DEC_VALUE) EXP DEC_VALUE
;
Expand All @@ -212,7 +227,7 @@ fragment FLOAT_LIT
fragment INF
: 'inf'
;
fragment NAN
fragment NAN
: 'nan'
;
fragment EXP
Expand Down Expand Up @@ -247,7 +262,7 @@ fragment UNDERSCORE
: '_'
;
fragment ESC_SEQ
: '\\' ('a'|'v'|'b'|'t'|'n'|'f'|'r'|'?'|'"'|'\''|'\\')
: '\\' ('a'|'v'|'b'|'t'|'n'|'f'|'r'|'?'|'"'|'\''|'\\'|'`')
| '\\' ('x'|'X') HEX_DIGIT HEX_DIGIT
| UNICODE_ESC
| OCTAL_ESC
Expand All @@ -269,4 +284,4 @@ fragment UNICODE_ESC
*/
ERRCHAR
: . -> channel(HIDDEN)
;
;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ syntaxStatement
: SYNTAX ASSIGN syntaxName SEMICOLON
;
syntaxName
: STRING_VALUE
: STRING_NAME
;
packageStatement
: PACKAGE packageName SEMICOLON
Expand All @@ -32,7 +32,7 @@ importStatement
: IMPORT PUBLIC? fileReference SEMICOLON
;
fileReference
: STRING_VALUE
: STRING_NAME
;
optionEntry
: OPTION option SEMICOLON
Expand Down Expand Up @@ -160,7 +160,7 @@ reservedFieldNames
: RESERVED reservedFieldName (COMMA reservedFieldName)* SEMICOLON
;
reservedFieldName
: STRING_VALUE
: STRING_NAME
;
field
: fieldModifier? typeReference fieldName ASSIGN tag fieldOptions? SEMICOLON
Expand Down Expand Up @@ -211,6 +211,7 @@ optionValue
: INTEGER_VALUE
| FLOAT_VALUE
| BOOLEAN_VALUE
| STRING_NAME
| STRING_VALUE
| IDENT
| textFormat
Expand All @@ -230,6 +231,7 @@ textFormatOptionValue
: INTEGER_VALUE
| FLOAT_VALUE
| BOOLEAN_VALUE
| STRING_NAME
| STRING_VALUE
| IDENT
;
Expand Down Expand Up @@ -276,4 +278,4 @@ ident
| BOOL
| STRING
| BYTES
;
;
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private void merge(DynamicMessage message) {
private Key createKey(String fieldName) {
Key key;
if (fieldName.startsWith("(")) {
String name = Util.removeFirstAndLastChar(fieldName);
String name = Util.trimStringName(fieldName);
if (name.startsWith(".")) {
name = name.substring(1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void exitReservedFieldNames(ProtoParser.ReservedFieldNamesContext ctx) {
UserType userType = context.peek(UserType.class);
for (ProtoParser.ReservedFieldNameContext fieldNameContext : ctx.reservedFieldName()) {
String fieldName = fieldNameContext.getText();
fieldName = Util.removeFirstAndLastChar(fieldName);
fieldName = Util.trimStringName(fieldName);
userType.addReservedFieldName(fieldName);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,14 @@ private DynamicMessage.Value getOptionValue(ProtoParser.OptionValueContext optio
} else if (optionValueContext.INTEGER_VALUE() != null) {
String text = optionValueContext.INTEGER_VALUE().getText();
optionValue = parseInteger(sourceCodeLocation, text);
} else if (optionValueContext.STRING_NAME() != null) {
String text = optionValueContext.STRING_NAME().getText();
// TODO: unescape
optionValue = DynamicMessage.Value.createString(sourceCodeLocation, Util.trimStringName(text));
} else if (optionValueContext.STRING_VALUE() != null) {
String text = optionValueContext.STRING_VALUE().getText();
// TODO: unescape
optionValue = DynamicMessage.Value.createString(sourceCodeLocation, Util.removeFirstAndLastChar(text));
optionValue = DynamicMessage.Value.createString(sourceCodeLocation, Util.trimStringValue(text));
} else if (optionValueContext.IDENT() != null) {
String text = optionValueContext.IDENT().getText();
optionValue = DynamicMessage.Value.createEnum(sourceCodeLocation, text);
Expand Down Expand Up @@ -142,10 +146,14 @@ private DynamicMessage.Value getTextFormatOptionValue(ProtoParser.TextFormatEntr
} else if (ctx.textFormatOptionValue().INTEGER_VALUE() != null) {
String text = ctx.textFormatOptionValue().INTEGER_VALUE().getText();
optionValue = parseInteger(sourceCodeLocation, text);
} else if (ctx.textFormatOptionValue().STRING_NAME() != null) {
String text = ctx.textFormatOptionValue().STRING_NAME().getText();
// TODO: unescape
optionValue = DynamicMessage.Value.createString(sourceCodeLocation, Util.trimStringName(text));
} else if (ctx.textFormatOptionValue().STRING_VALUE() != null) {
String text = ctx.textFormatOptionValue().STRING_VALUE().getText();
// TODO: unescape
optionValue = DynamicMessage.Value.createString(sourceCodeLocation, Util.removeFirstAndLastChar(text));
optionValue = DynamicMessage.Value.createString(sourceCodeLocation, Util.trimStringValue(text));
} else if (ctx.textFormatOptionValue().IDENT() != null) {
String text = ctx.textFormatOptionValue().IDENT().getText();
optionValue = DynamicMessage.Value.createEnum(sourceCodeLocation, text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private boolean isCommentBlockOwner(Token token) {
public void exitSyntaxStatement(ProtoParser.SyntaxStatementContext ctx) {
Proto proto = context.peek(Proto.class);
String text = ctx.syntaxName().getText();
String value = Util.removeFirstAndLastChar(text);
String value = Util.trimStringName(text);
Syntax syntax = new Syntax(proto, value);
syntax.setSourceCodeLocation(getSourceCodeLocation(ctx));
proto.setSyntax(syntax);
Expand All @@ -93,7 +93,7 @@ public void exitPackageStatement(ProtoParser.PackageStatementContext ctx) {
public void exitImportStatement(ProtoParser.ImportStatementContext ctx) {
Proto proto = context.peek(Proto.class);
String text = ctx.fileReference().getText();
String fileName = Util.removeFirstAndLastChar(text);
String fileName = Util.trimStringName(text);
Import anImport = new Import(proto, fileName, ctx.PUBLIC() != null);
anImport.setSourceCodeLocation(getSourceCodeLocation(ctx));
proto.addImport(anImport);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.protostuff.compiler.parser;

import com.google.common.base.Preconditions;

import javax.annotation.ParametersAreNonnullByDefault;

/**
Expand All @@ -26,13 +27,42 @@ private Util() {
* @param text given string
*
* @return substring of given string - without first and last characters
* @deprecated replaced by {@link #trimStringName(String)}
*/
public static String removeFirstAndLastChar(String text) {
return trimStringName(text);
}

/**
* Remove first and last character from given string name and return result.
*
* @param text given string
*
* @return substring of given string - without first and last characters
*/
public static String trimStringName(String text) {
Preconditions.checkNotNull(text, "text can not be null");
int n = text.length();
return text.substring(1, n - 1);
}

/**
* Remove first and last character from given string value and return result.
*
* A string value can be wrapped by either a backtick, `, or triple double
* quote, """.
*
* @param text given string value
*
* @return substring of given string - without first and last characters
*/
public static String trimStringValue(String text) {
Preconditions.checkNotNull(text, "text can not be null");
int size = text.startsWith("`") ? 1 : 3;
int n = text.length();
return text.substring(size, n - size);
}

/**
* Returns file name by given absolute or relative file location.
* TODO: remove unused?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import org.junit.jupiter.api.Test;

import static io.protostuff.compiler.parser.Util.removeFirstAndLastChar;
import static io.protostuff.compiler.parser.Util.trimStringName;
import static io.protostuff.compiler.parser.Util.trimStringValue;
import static org.junit.jupiter.api.Assertions.assertEquals;

/**
Expand All @@ -11,8 +12,13 @@
public class UtilTest {

@Test
public void testRemoveQuotes_expected() throws Exception {
assertEquals("abc", removeFirstAndLastChar("\"abc\""));
public void testTrimStringName_expected() throws Exception {
assertEquals("abc", trimStringName("\"abc\""));
}

}
@Test
public void testTrimStringValue_expected() throws Exception {
assertEquals("abc", trimStringValue("`abc`"));
assertEquals("abc", trimStringValue("\"\"\"abc\"\"\""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ message TestAllTypes {
optional bool default_bool = 73 [default = true];
optional string default_string = 74 [default = "hello"];
optional bytes default_bytes = 75 [default = "world"];
optional string default_m_string = 76 [default = `hello
world`];

optional NestedEnum default_nested_enum = 81 [default = BAR];
optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
Expand Down Expand Up @@ -560,6 +562,9 @@ message TestExtremeDefaultValues {
optional string string_piece_with_zero = 25 [ctype = STRING_PIECE, default = "ab\000c"];
optional string cord_with_zero = 26 [ctype = CORD, default = "12\0003"];
optional string replacement_string = 27 [default = "${unknown}"];
optional string tick_multiline_string = 28 [default=`backtick
multiline
default`];
}

message SparseEnumMessage {
Expand Down
Loading