Unclearness in the specification

85 views
Skip to first unread message

Mattias Hansson

unread,
Oct 21, 2023, 11:43:45 AM10/21/23
to Protocol Buffers
I am currently trying to implement a protobuf parser but it's a bit unclear to me how I should interpret some parts of the specification.

Lets start with RPC option. Options for normal fields and enum fields are pretty clear.

Here's the specification for normal fields:
field = [ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" fieldOptions = fieldOption { "," fieldOption } fieldOption = optionName "=" constant

Here's the specification for enum fields:
enum = "enum" enumName enumBody enumBody = "{" { option | enumField | emptyStatement | reserved } "}" enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" enumValueOption = optionName "=" constant

Both fields boils down to optionName which is specified as:
optionName = ( ident | "(" ["."] fullIdent ")" ) 
Here's the specification for RPC:
service = "service" serviceName "{" { option | rpc | emptyStatement } "}" rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ] messageType ")" (( "{" {option | emptyStatement } "}" ) | ";")

RPC refers to plain option. Does this mean that the following is valid and intended syntax?
rpc Foo (Req) returns (Res);
rpc Foo (Req) returns (Res) {option opt1 = "opt1"; option opt2 = true; };
rpc Foo (Req) returns (Res) {option opt1 = "opt1"; ;;; option opt2 = true; ;;;};

I added number 3, because it seems like repetition is allowed together with emptyStatement. As a side note, I could not find any examples with RPC options as inspiration or to clear things up.

Further, I also find the specification for optionName a bit unclear.
Here's the specification for option and optionName:
option = "option" optionName "=" constant ";" optionName = ( ident | "(" ["."] fullIdent ")" )
optionName does not seem to allow for repetition and fullIdent is only allowed within parenthesis(custom option). However multiple examples on https://protobuf.dev/programming-guides/proto3/#option-targets use custom-like options on the format:
option (bar).baz = "value";

For me it's pretty clear that the following optionNames are allowed:
foo
(foo)
(foo.bar)
(.foo)
(.foo.bar)

I don't really get which part of the specification that states that "baz", in the example above, is allowed outside of the parenthesis.

Thanks in advance,

/Mattias

Em Rauch

unread,
Oct 23, 2023, 10:53:26 AM10/23/23
to Protocol Buffers
This part of the official grammar unfortunately unclear; you may find Buf's reverse engineering of the protobuf grammar to be more clear on this point for your usecase: https://protobuf.com/docs/language-spec
Reply all
Reply to author
Forward
0 new messages