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.

Warning about customtype: It is your responsibility to test all cases of your marshaling, unmarshaling and size methods implemented for your custom type.

Issues with customtype include:

  • A Bytes method is not allowed.
  • Defining a customtype as a fake proto message is broken.
  • proto.Clone is broken.
  • Using a proto message as a customtype is not allowed.
  • cusomtype of type map can not UnmarshalText
  • customtype of type struct cannot jsonpb unmarshal

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.

#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

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.