gogoprotobuf Extensions

Here is an example.proto which uses most of the gogoprotobuf code generation plugins.

Please also look at the example Makefile which shows how to specify the descriptor.proto and gogo.proto in your proto_path

The documentation at http://godoc.org/github.com/gogo/protobuf/gogoproto describes the extensions made to goprotobuf in more detail.

Also see http://godoc.org/github.com/gogo/protobuf/plugin/ for documentation of each of the extensions which have their own plugins.

Fast Marshalling and Unmarshalling

Generating a Marshal, MarshalTo, Size (or ProtoSize) and Unmarshal method for a struct results in faster marshalling and unmarshalling than when using reflect.

See BenchComparison for a comparison between reflect and generated code used for marshalling and unmarshalling.

More Canonical Go Structures

Lots of times working with a goprotobuf struct will lead you to a place where you create another struct that is easier to work with and then have a function to copy the values between the two structs.

You might also find that basic structs that started their life as part of an API need to be sent over the wire. With gob, you could just send it. With goprotobuf, you need to make a new struct.

gogoprotobuf tries to fix these problems with the nullable, embed, customtype, customname, casttype, castkey and castvalue field extensions.

Warning about nullable: according to the Protocol Buffer specification, you should be able to tell whether a field is set or unset. With the option nullable=false this feature is lost, since your non-nullable fields will always be set.

Goprotobuf Compatibility

Gogoprotobuf is compatible with Goprotobuf, because it is compatible with protocol buffers (see the section on tests below).

Gogoprotobuf generates the same code as goprotobuf if no extensions are used.

The enumprefix, getters and stringer extensions can be used to remove some of the unnecessary code generated by goprotobuf.

Less Typing

The Protocol Buffer language is very parseable and extra code can be easily generated for structures.

Helper methods, functions and interfaces can be generated by triggering certain extensions like gostring.

Issues with Compare include:

  • Oneof is not supported yet
  • Not all Well Known Types are supported yet
  • Maps are not supported

#Peace of Mind

Test and Benchmark generation is done with the following extensions:

More Serialization Formats

Other serialization formats like xml and json typically use reflect to marshal and unmarshal structured data. Manipulating these structs into something other than the default Go requires editing tags. The following extensions provide ways of editing these tags for the generated protobuf structs.

Here is a longer explanation of jsontag and moretags

File Options

Each of the boolean message and enum extensions also have a file extension:

  • marshaler_all
  • sizer_all
  • protosizer_all
  • unmarshaler_all
  • unsafe_marshaler_all
  • unsafe_unmarshaler_all
  • stable_marshaler_all
  • goproto_enum_prefix_all
  • goproto_getters_all
  • goproto_stringer_all
  • goproto_enum_stringer_all
  • goproto_extensions_map_all
  • goproto_unrecognized_all
  • gostring_all
  • onlyone_all
  • equal_all
  • compare_all
  • verbose_equal_all
  • stringer_all
  • enum_stringer_all
  • face_all
  • description_all
  • populate_all
  • testgen_all
  • benchgen_all
  • enumdecl_all
  • typedecl_all
  • messagename_all

Each of these are the same as their Message Option counterparts, except they apply to all messages in the file. Their Message option counterparts can also be used to overwrite their effect.

Tests

  • The normal barrage of tests are run with: make tests
  • A few weird tests: make testall
  • Tests for compatibility with golang/protobuf are handled by a different project harmonytests, since it requires goprotobuf.
  • Cross version tests are made with Travis CI.
  • GRPC Tests are also handled by a different project grpctests, since it depends on a lot of grpc libraries.
  • Thanks to go-fuzz we have proper fuzztests.