diff --git a/src/protobuffs_parser.yrl b/src/protobuffs_parser.yrl index fe72607..95ef5d2 100644 --- a/src/protobuffs_parser.yrl +++ b/src/protobuffs_parser.yrl @@ -16,6 +16,7 @@ g_header -> g_var g_var '=' g_value ';' : {'$1', '$2', '$4'}. g_message -> g_var g_var '{' g_elements '}' : {'$1', safe_string('$2'), '$4'}. g_message -> g_var g_var '{' g_rpcs '}' : {'$1', safe_string('$2'), '$4'}. +g_message -> g_var g_var '{' '}' : {'$1', safe_string('$2'), []}. g_rpcs -> g_rpc : ['$1']. g_rpcs -> g_rpc g_rpcs : ['$1' | '$2']. diff --git a/src/protobuffs_scanner.xrl b/src/protobuffs_scanner.xrl index 47da942..e8a9602 100644 --- a/src/protobuffs_scanner.xrl +++ b/src/protobuffs_scanner.xrl @@ -11,7 +11,7 @@ Rules. {L}({L}|{D})* : {token, {var, TokenLine,list_to_atom(TokenChars)}}. '({L}|{D})+' : S = strip(TokenChars,TokenLen), {token,{string,TokenLine,S}}. -"({L}|{D}|/)+" : S = strip(TokenChars,TokenLen), +"({L}|{D}|/)*" : S = strip(TokenChars,TokenLen), {token,{string,TokenLine,S}}. {S} : {token, {list_to_atom(TokenChars),TokenLine}}. {WS}+ : skip_token. diff --git a/test/erlang_protobuffs_SUITE_data/empty.proto b/test/erlang_protobuffs_SUITE_data/empty.proto index 081b469..bcb8a0b 100644 --- a/test/erlang_protobuffs_SUITE_data/empty.proto +++ b/test/erlang_protobuffs_SUITE_data/empty.proto @@ -14,4 +14,7 @@ message Empty { optional bool val1 = 13; optional string str1 = 14; optional bytes bit1 = 15; + optional EmptyMessage msg = 16; + message EmptyMessage { + } } diff --git a/test/erlang_protobuffs_SUITE_data/hasdefault.proto b/test/erlang_protobuffs_SUITE_data/hasdefault.proto index 6ae4e82..4497312 100644 --- a/test/erlang_protobuffs_SUITE_data/hasdefault.proto +++ b/test/erlang_protobuffs_SUITE_data/hasdefault.proto @@ -14,5 +14,6 @@ message WithDefault { required sfixed64 int10 = 12 [default = 10]; required bool val1 = 13 [default = true]; required string str1 = 14 [default = "test"]; + required string str2 = 15 [default = ""]; } diff --git a/test/protobuffs_eqc.erl b/test/protobuffs_eqc.erl index 0a548dd..7b665a5 100644 --- a/test/protobuffs_eqc.erl +++ b/test/protobuffs_eqc.erl @@ -24,7 +24,7 @@ sint64() -> choose(-16#8000000000000000,16#7fffffffffffffff). string() -> - non_empty(list(char())). + list(char()). value() -> oneof([{real(),double}, @@ -135,7 +135,8 @@ prop_protobuffs_empty() -> default(undefined, sint64()), default(undefined, bool()), default(undefined, string()), - default(undefined, binary())}}, + default(undefined, binary()), + default(undefined, {empty_emptymessage})}}, begin Decoded = empty_pb:decode_empty(empty_pb:encode_empty(Empty)), compare_messages(Empty,Decoded) @@ -163,6 +164,7 @@ prop_protobuffs_has_default() -> default(undefined, sint32()), default(undefined, sint64()), default(undefined, bool()), + default(undefined, string()), default(undefined, string())}}, begin Decoded = hasdefault_pb:decode_withdefault(hasdefault_pb:encode_withdefault(Withdefault)), diff --git a/test/protobuffs_parser_tests.erl b/test/protobuffs_parser_tests.erl index ae281d3..1a63946 100644 --- a/test/protobuffs_parser_tests.erl +++ b/test/protobuffs_parser_tests.erl @@ -26,9 +26,9 @@ message_test_() -> [?_assertMatch({ok,[{message, "Test",[{1,required,"string","name",none}]}]},Parsed)]. message_default_test_() -> - {ok,Result,1} = protobuffs_scanner:string("message Test { optional float value = 1 [default=0.01]; }"), + {ok,Result,1} = protobuffs_scanner:string("message Test { optional float value = 1 [default=0.01]; optional string stringvalue = 2 [default=\"\"];}"), Parsed = protobuffs_parser:parse(Result), - [?_assertMatch({ok,[{message, "Test",[{1,optional,"float","value",0.01}]}]},Parsed)]. + [?_assertMatch({ok,[{message, "Test",[{1,optional,"float","value",0.01},{2,optional,"string","stringvalue",""}]}]},Parsed)]. packed_test_() -> {ok,Result,1} = protobuffs_scanner:string("message Test { repeated float values = 1 [packed=true]; }"), @@ -70,3 +70,7 @@ inner_option_test_() -> Parsed = protobuffs_parser:parse(Result), [?_assertMatch({ok,[{message, "Foo", [{option,message_set_wire_format,true}]}]}, Parsed)]. +nested_message_test_() -> + {ok,Result,1} = protobuffs_scanner:string("message Test { required Nested nested = 1; message Nested { } }"), + Parsed = protobuffs_parser:parse(Result), + [?_assertMatch({ok,[{message, "Test",[{1, required, "Nested", "nested", none}, {message, "Nested", []}]}]},Parsed)]. diff --git a/test/protobuffs_tests.erl b/test/protobuffs_tests.erl index a7674e8..55e6dc1 100644 --- a/test/protobuffs_tests.erl +++ b/test/protobuffs_tests.erl @@ -45,6 +45,7 @@ parse_empty_file_test_() -> Path = filename:absname("../test/erlang_protobuffs_SUITE_data/empty.proto"), io:format("Test path ~p~n",[Path]), [{message, "Empty", Messages}] = parse(Path), + {message, "EmptyMessage", _EmptyMessage} = lists:keyfind("EmptyMessage",2,Messages), [?_assertMatch({1,optional,"double","real1",none},lists:keyfind(1,1,Messages)), ?_assertMatch({2,optional,"float","real2",none},lists:keyfind(2,1,Messages)), ?_assertMatch({3,optional,"int32","int1",none},lists:keyfind(3,1,Messages)), @@ -59,7 +60,8 @@ parse_empty_file_test_() -> ?_assertMatch({12,optional,"sfixed64","int10",none},lists:keyfind(12,1,Messages)), ?_assertMatch({13,optional,"bool","val1",none},lists:keyfind(13,1,Messages)), ?_assertMatch({14,optional,"string","str1",none},lists:keyfind(14,1,Messages)), - ?_assertMatch({15,optional,"bytes","bit1",none},lists:keyfind(15,1,Messages))]. + ?_assertMatch({15,optional,"bytes","bit1",none},lists:keyfind(15,1,Messages)), + ?_assertMatch({16,optional,"EmptyMessage","msg",none},lists:keyfind(16,1,Messages))]. parse_has_default_test_() -> Path = filename:absname("../test/erlang_protobuffs_SUITE_data/hasdefault.proto"), @@ -77,7 +79,8 @@ parse_has_default_test_() -> ?_assertMatch({11,required,"sfixed32","int9",9},lists:keyfind(11,1,Messages)), ?_assertMatch({12,required,"sfixed64","int10",10},lists:keyfind(12,1,Messages)), ?_assertMatch({13,required,"bool","val1",true},lists:keyfind(13,1,Messages)), - ?_assertMatch({14,required,"string","str1","test"},lists:keyfind(14,1,Messages))]. + ?_assertMatch({14,required,"string","str1","test"},lists:keyfind(14,1,Messages)), + ?_assertMatch({15,required,"string","str2",""},lists:keyfind(15,1,Messages))]. parse_simple_test_() -> Path = filename:absname("../test/erlang_protobuffs_SUITE_data/simple.proto"),