14
votes

Besides the rather short Google provided style guide, here are my thoughts on naming Google Protocol Buffer messages.

  1. Use "Message" at the end of message types names.

    • This makes it easy to see in source code that a class is a protobuf generated class. This also has the advantage that if I have a rich domain specific class, then it can have the real name, say AddressBookMessage for the protobuf class and AddressBook for the real class.
  2. For Java users, it appears that having java_outer_classname end in Protos is standard.

    • I didn't notice this initially, so my current protobuf classes are in com.example.project.protobuf.MyProtos , but I don't see a reason to keep it there given that we need to have a containing class, so it could be moved to com.example.protobuf.MyProtos unless there are no classes in the project's top package.
  3. Start enums at 0 to match C/C++.

  4. Use a singular name for a repeated field.

    • Most of the generated methods sound better with a singular field name, even if it is repeated, e.g. message->add_child(), instead of message->add_children() if one had a repeated child field.

Are there any other standards people use or differ from these?

4
What do you mean by "Start enums at 0 to match C/C++"? - bialix
@bialix, assigning values to the enum members, the Protobuf style page show them starting at 1, see "enum Foo" at code.google.com/apis/protocolbuffers/docs/style.html. But I see other examples starting at 0 on other pages. - Blair Zajac

4 Answers

12
votes

Disclaimer: answer from a Googler using protobufs on a daily basis. I'm by no means representing Google in any way.

  1. Don't do that. Compiled protocol buffers are just a class definition specified by the language you are using, with some improvements. Adding "Message" is extra verbosity. Normally you just use protocol buffers without other class definitions, and even if you use other class definitions, just import java_outer_classname and do a dot from that. You can even put full path of a thing in code to erase one line of import, no problem.

  2. Although not specified officially, it sounds like a good suggestion, because normally you put more than one proto inside a folder.

  3. You normally start with 0. See the protocol buffer language guide.

  4. Yes. Read the following to get some feeling using it: https://developers.google.com/protocol-buffers/docs/javatutorial

8
votes

I don't agree with answer 4. In the linked article I can find only examples like this:

repeated PhoneNumber phones = 4;
repeated Person people = 1;

And even in https://developers.google.com/protocol-buffers/docs/proto3 we only find plurals:

repeated Result results = 1;
repeated string snippets = 3;
3
votes

What you're looking for is the https://cloud.google.com/apis/design/ which talks about protobuf/gRPC design conventions that are used in Google's own APIs.

The protobuf Style Guide (https://developers.google.com/protocol-buffers/docs/style) is rather short as you said.

0
votes

It seems Google added a guideline for repeated field names (point 4) at https://developers.google.com/protocol-buffers/docs/style in the meanwhile:

Use pluralized names for repeated fields.

repeated string keys = 1;
...
repeated MyMessage accounts = 17;

It generates one bad function name for the add_<field_name> member function:

// Bad method name.
auto* const newKey = msg.add_keys();
// OK!
auto* const anotherNewKey = msg.mutable_keys()->Add();
// OK!
auto const * const allKeys = msg.keys();
auto const& firstKeys = msg.keys(0);

One could argue that the first method is redundant anyway. By using the mutable_<field_name> member function I do not see any problems regarding ugly method names if plural field names are used for repeated fields.

Therefore I will try to follow this guideline from now on. Another reason for it: We also tend to use plural variable names for containers/collections in C++, e.g.

auto keys = std::vector<std::string>{};