1*1c12ee1eSDan Willemsen# Go support for Protocol Buffers 2*1c12ee1eSDan Willemsen 3*1c12ee1eSDan Willemsen[](https://pkg.go.dev/google.golang.org/protobuf) 4*1c12ee1eSDan Willemsen[](https://travis-ci.org/protocolbuffers/protobuf-go) 5*1c12ee1eSDan Willemsen 6*1c12ee1eSDan WillemsenThis project hosts the Go implementation for 7*1c12ee1eSDan Willemsen[protocol buffers](https://protobuf.dev), which is a 8*1c12ee1eSDan Willemsenlanguage-neutral, platform-neutral, extensible mechanism for serializing 9*1c12ee1eSDan Willemsenstructured data. The protocol buffer language is a language for specifying the 10*1c12ee1eSDan Willemsenschema for structured data. This schema is compiled into language specific 11*1c12ee1eSDan Willemsenbindings. This project provides both a tool to generate Go code for the 12*1c12ee1eSDan Willemsenprotocol buffer language, and also the runtime implementation to handle 13*1c12ee1eSDan Willemsenserialization of messages in Go. See the 14*1c12ee1eSDan Willemsen[protocol buffer developer guide](https://protobuf.dev/overview) 15*1c12ee1eSDan Willemsenfor more information about protocol buffers themselves. 16*1c12ee1eSDan Willemsen 17*1c12ee1eSDan WillemsenThis project is comprised of two components: 18*1c12ee1eSDan Willemsen 19*1c12ee1eSDan Willemsen* Code generator: The 20*1c12ee1eSDan Willemsen [`protoc-gen-go`](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go) 21*1c12ee1eSDan Willemsen tool is a compiler plugin to `protoc`, the protocol buffer compiler. It 22*1c12ee1eSDan Willemsen augments the `protoc` compiler so that it knows how to 23*1c12ee1eSDan Willemsen [generate Go specific code for a given `.proto` file](https://protobuf.dev/reference/go/go-generated). 24*1c12ee1eSDan Willemsen 25*1c12ee1eSDan Willemsen* Runtime library: The 26*1c12ee1eSDan Willemsen [`protobuf`](https://pkg.go.dev/mod/google.golang.org/protobuf) module 27*1c12ee1eSDan Willemsen contains a set of Go packages that form the runtime implementation of 28*1c12ee1eSDan Willemsen protobufs in Go. This provides the set of interfaces that 29*1c12ee1eSDan Willemsen [define what a message is](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect) 30*1c12ee1eSDan Willemsen and functionality to serialize message in various formats (e.g., 31*1c12ee1eSDan Willemsen [wire](https://pkg.go.dev/google.golang.org/protobuf/proto), 32*1c12ee1eSDan Willemsen [JSON](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson), 33*1c12ee1eSDan Willemsen and 34*1c12ee1eSDan Willemsen [text](https://pkg.go.dev/google.golang.org/protobuf/encoding/prototext)). 35*1c12ee1eSDan Willemsen 36*1c12ee1eSDan WillemsenSee the 37*1c12ee1eSDan Willemsen[developer guide for protocol buffers in Go](https://protobuf.dev/getting-started/gotutorial) 38*1c12ee1eSDan Willemsenfor a general guide for how to get started using protobufs in Go. 39*1c12ee1eSDan Willemsen 40*1c12ee1eSDan WillemsenThis project is the second major revision of the Go protocol buffer API 41*1c12ee1eSDan Willemsenimplemented by the 42*1c12ee1eSDan Willemsen[`google.golang.org/protobuf`](https://pkg.go.dev/mod/google.golang.org/protobuf) 43*1c12ee1eSDan Willemsenmodule. The first major version is implemented by the 44*1c12ee1eSDan Willemsen[`github.com/golang/protobuf`](https://pkg.go.dev/mod/github.com/golang/protobuf) 45*1c12ee1eSDan Willemsenmodule. 46*1c12ee1eSDan Willemsen 47*1c12ee1eSDan Willemsen## Package index 48*1c12ee1eSDan Willemsen 49*1c12ee1eSDan WillemsenSummary of the packages provided by this module: 50*1c12ee1eSDan Willemsen 51*1c12ee1eSDan Willemsen* [`proto`](https://pkg.go.dev/google.golang.org/protobuf/proto): Package 52*1c12ee1eSDan Willemsen `proto` provides functions operating on protobuf messages such as cloning, 53*1c12ee1eSDan Willemsen merging, and checking equality, as well as binary serialization. 54*1c12ee1eSDan Willemsen* [`encoding/protojson`](https://pkg.go.dev/google.golang.org/protobuf/encoding/protojson): 55*1c12ee1eSDan Willemsen Package `protojson` serializes protobuf messages as JSON. 56*1c12ee1eSDan Willemsen* [`encoding/prototext`](https://pkg.go.dev/google.golang.org/protobuf/encoding/prototext): 57*1c12ee1eSDan Willemsen Package `prototext` serializes protobuf messages as the text format. 58*1c12ee1eSDan Willemsen* [`encoding/protowire`](https://pkg.go.dev/google.golang.org/protobuf/encoding/protowire): 59*1c12ee1eSDan Willemsen Package `protowire` parses and formats the low-level raw wire encoding. Most 60*1c12ee1eSDan Willemsen users should use package `proto` to serialize messages in the wire format. 61*1c12ee1eSDan Willemsen* [`reflect/protoreflect`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect): 62*1c12ee1eSDan Willemsen Package `protoreflect` provides interfaces to dynamically manipulate 63*1c12ee1eSDan Willemsen protobuf messages. 64*1c12ee1eSDan Willemsen* [`reflect/protoregistry`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoregistry): 65*1c12ee1eSDan Willemsen Package `protoregistry` provides data structures to register and lookup 66*1c12ee1eSDan Willemsen protobuf descriptor types. 67*1c12ee1eSDan Willemsen* [`reflect/protodesc`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protodesc): 68*1c12ee1eSDan Willemsen Package `protodesc` provides functionality for converting 69*1c12ee1eSDan Willemsen `descriptorpb.FileDescriptorProto` messages to/from the reflective 70*1c12ee1eSDan Willemsen `protoreflect.FileDescriptor`. 71*1c12ee1eSDan Willemsen* [`reflect/protopath`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protopath): 72*1c12ee1eSDan Willemsen Package `protopath` provides a representation of a sequence of 73*1c12ee1eSDan Willemsen protobuf reflection operations on a message. 74*1c12ee1eSDan Willemsen* [`reflect/protorange`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protorange): 75*1c12ee1eSDan Willemsen Package `protorange` provides functionality to traverse a protobuf message. 76*1c12ee1eSDan Willemsen* [`testing/protocmp`](https://pkg.go.dev/google.golang.org/protobuf/testing/protocmp): 77*1c12ee1eSDan Willemsen Package `protocmp` provides protobuf specific options for the `cmp` package. 78*1c12ee1eSDan Willemsen* [`testing/protopack`](https://pkg.go.dev/google.golang.org/protobuf/testing/protopack): 79*1c12ee1eSDan Willemsen Package `protopack` aids manual encoding and decoding of the wire format. 80*1c12ee1eSDan Willemsen* [`testing/prototest`](https://pkg.go.dev/google.golang.org/protobuf/testing/prototest): 81*1c12ee1eSDan Willemsen Package `prototest` exercises the protobuf reflection implementation for 82*1c12ee1eSDan Willemsen concrete message types. 83*1c12ee1eSDan Willemsen* [`types/dynamicpb`](https://pkg.go.dev/google.golang.org/protobuf/types/dynamicpb): 84*1c12ee1eSDan Willemsen Package `dynamicpb` creates protobuf messages at runtime from protobuf 85*1c12ee1eSDan Willemsen descriptors. 86*1c12ee1eSDan Willemsen* [`types/known/anypb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/anypb): 87*1c12ee1eSDan Willemsen Package `anypb` is the generated package for `google/protobuf/any.proto`. 88*1c12ee1eSDan Willemsen* [`types/known/timestamppb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/timestamppb): 89*1c12ee1eSDan Willemsen Package `timestamppb` is the generated package for 90*1c12ee1eSDan Willemsen `google/protobuf/timestamp.proto`. 91*1c12ee1eSDan Willemsen* [`types/known/durationpb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/durationpb): 92*1c12ee1eSDan Willemsen Package `durationpb` is the generated package for 93*1c12ee1eSDan Willemsen `google/protobuf/duration.proto`. 94*1c12ee1eSDan Willemsen* [`types/known/wrapperspb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/wrapperspb): 95*1c12ee1eSDan Willemsen Package `wrapperspb` is the generated package for 96*1c12ee1eSDan Willemsen `google/protobuf/wrappers.proto`. 97*1c12ee1eSDan Willemsen* [`types/known/structpb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb): 98*1c12ee1eSDan Willemsen Package `structpb` is the generated package for 99*1c12ee1eSDan Willemsen `google/protobuf/struct.proto`. 100*1c12ee1eSDan Willemsen* [`types/known/fieldmaskpb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/fieldmaskpb): 101*1c12ee1eSDan Willemsen Package `fieldmaskpb` is the generated package for 102*1c12ee1eSDan Willemsen `google/protobuf/field_mask.proto`. 103*1c12ee1eSDan Willemsen* [`types/known/apipb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/apipb): 104*1c12ee1eSDan Willemsen Package `apipb` is the generated package for 105*1c12ee1eSDan Willemsen `google/protobuf/api.proto`. 106*1c12ee1eSDan Willemsen* [`types/known/typepb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/typepb): 107*1c12ee1eSDan Willemsen Package `typepb` is the generated package for 108*1c12ee1eSDan Willemsen `google/protobuf/type.proto`. 109*1c12ee1eSDan Willemsen* [`types/known/sourcecontextpb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/sourcecontextpb): 110*1c12ee1eSDan Willemsen Package `sourcecontextpb` is the generated package for 111*1c12ee1eSDan Willemsen `google/protobuf/source_context.proto`. 112*1c12ee1eSDan Willemsen* [`types/known/emptypb`](https://pkg.go.dev/google.golang.org/protobuf/types/known/emptypb): 113*1c12ee1eSDan Willemsen Package `emptypb` is the generated package for 114*1c12ee1eSDan Willemsen `google/protobuf/empty.proto`. 115*1c12ee1eSDan Willemsen* [`types/descriptorpb`](https://pkg.go.dev/google.golang.org/protobuf/types/descriptorpb): 116*1c12ee1eSDan Willemsen Package `descriptorpb` is the generated package for 117*1c12ee1eSDan Willemsen `google/protobuf/descriptor.proto`. 118*1c12ee1eSDan Willemsen* [`types/pluginpb`](https://pkg.go.dev/google.golang.org/protobuf/types/pluginpb): 119*1c12ee1eSDan Willemsen Package `pluginpb` is the generated package for 120*1c12ee1eSDan Willemsen `google/protobuf/compiler/plugin.proto`. 121*1c12ee1eSDan Willemsen* [`compiler/protogen`](https://pkg.go.dev/google.golang.org/protobuf/compiler/protogen): 122*1c12ee1eSDan Willemsen Package `protogen` provides support for writing protoc plugins. 123*1c12ee1eSDan Willemsen* [`cmd/protoc-gen-go`](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go): 124*1c12ee1eSDan Willemsen The `protoc-gen-go` binary is a protoc plugin to generate a Go protocol 125*1c12ee1eSDan Willemsen buffer package. 126*1c12ee1eSDan Willemsen 127*1c12ee1eSDan Willemsen## Reporting issues 128*1c12ee1eSDan Willemsen 129*1c12ee1eSDan WillemsenThe issue tracker for this project is currently located at 130*1c12ee1eSDan Willemsen[golang/protobuf](https://github.com/golang/protobuf/issues). 131*1c12ee1eSDan Willemsen 132*1c12ee1eSDan WillemsenPlease report any issues there with a sufficient description of the bug or 133*1c12ee1eSDan Willemsenfeature request. Bug reports should ideally be accompanied by a minimal 134*1c12ee1eSDan Willemsenreproduction of the issue. Irreproducible bugs are difficult to diagnose and fix 135*1c12ee1eSDan Willemsen(and likely to be closed after some period of time). Bug reports must specify 136*1c12ee1eSDan Willemsenthe version of the 137*1c12ee1eSDan Willemsen[Go protocol buffer module](https://github.com/protocolbuffers/protobuf-go/releases) 138*1c12ee1eSDan Willemsenand also the version of the 139*1c12ee1eSDan Willemsen[protocol buffer toolchain](https://github.com/protocolbuffers/protobuf/releases) 140*1c12ee1eSDan Willemsenbeing used. 141*1c12ee1eSDan Willemsen 142*1c12ee1eSDan Willemsen## Contributing 143*1c12ee1eSDan Willemsen 144*1c12ee1eSDan WillemsenThis project is open-source and accepts contributions. See the 145*1c12ee1eSDan Willemsen[contribution guide](https://github.com/protocolbuffers/protobuf-go/blob/master/CONTRIBUTING.md) 146*1c12ee1eSDan Willemsenfor more information. 147*1c12ee1eSDan Willemsen 148*1c12ee1eSDan Willemsen## Compatibility 149*1c12ee1eSDan Willemsen 150*1c12ee1eSDan WillemsenThis module and the generated code are expected to be stable over time. However, 151*1c12ee1eSDan Willemsenwe reserve the right to make breaking changes without notice for the following 152*1c12ee1eSDan Willemsenreasons: 153*1c12ee1eSDan Willemsen 154*1c12ee1eSDan Willemsen* **Security:** A security issue in the specification or implementation may 155*1c12ee1eSDan Willemsen come to light whose resolution requires breaking compatibility. We reserve 156*1c12ee1eSDan Willemsen the right to address such issues. 157*1c12ee1eSDan Willemsen* **Unspecified behavior:** There are some aspects of the protocol buffer 158*1c12ee1eSDan Willemsen specification that are undefined. Programs that depend on unspecified 159*1c12ee1eSDan Willemsen behavior may break in future releases. 160*1c12ee1eSDan Willemsen* **Specification changes:** It may become necessary to address an 161*1c12ee1eSDan Willemsen inconsistency, incompleteness, or change in the protocol buffer 162*1c12ee1eSDan Willemsen specification, which may affect the behavior of existing programs. We 163*1c12ee1eSDan Willemsen reserve the right to address such changes. 164*1c12ee1eSDan Willemsen* **Bugs:** If a package has a bug that violates correctness, a program 165*1c12ee1eSDan Willemsen depending on the buggy behavior may break if the bug is fixed. We reserve 166*1c12ee1eSDan Willemsen the right to fix such bugs. 167*1c12ee1eSDan Willemsen* **Generated additions**: We reserve the right to add new declarations to 168*1c12ee1eSDan Willemsen generated Go packages of `.proto` files. This includes declared constants, 169*1c12ee1eSDan Willemsen variables, functions, types, fields in structs, and methods on types. This 170*1c12ee1eSDan Willemsen may break attempts at injecting additional code on top of what is generated 171*1c12ee1eSDan Willemsen by `protoc-gen-go`. Such practice is not supported by this project. 172*1c12ee1eSDan Willemsen* **Internal changes**: We reserve the right to add, modify, and remove 173*1c12ee1eSDan Willemsen internal code, which includes all unexported declarations, the 174*1c12ee1eSDan Willemsen [`protoc-gen-go/internal_gengo`](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo) 175*1c12ee1eSDan Willemsen package, the 176*1c12ee1eSDan Willemsen [`runtime/protoimpl`](https://pkg.go.dev/google.golang.org/protobuf/runtime/protoimpl?tab=doc) 177*1c12ee1eSDan Willemsen package, and all packages under 178*1c12ee1eSDan Willemsen [`internal`](https://pkg.go.dev/google.golang.org/protobuf/internal). 179*1c12ee1eSDan Willemsen 180*1c12ee1eSDan WillemsenAny breaking changes outside of these will be announced 6 months in advance to 181*1c12ee1eSDan Willemsen[[email protected]](https://groups.google.com/forum/#!forum/protobuf). 182*1c12ee1eSDan Willemsen 183*1c12ee1eSDan WillemsenUsers should use generated code produced by a version of 184*1c12ee1eSDan Willemsen[`protoc-gen-go`](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go) 185*1c12ee1eSDan Willemsenthat is identical to the runtime version provided by the 186*1c12ee1eSDan Willemsen[protobuf module](https://pkg.go.dev/mod/google.golang.org/protobuf). This 187*1c12ee1eSDan Willemsenproject promises that the runtime remains compatible with code produced by a 188*1c12ee1eSDan Willemsenversion of the generator that is no older than 1 year from the version of the 189*1c12ee1eSDan Willemsenruntime used, according to the release dates of the minor version. Generated 190*1c12ee1eSDan Willemsencode is expected to use a runtime version that is at least as new as the 191*1c12ee1eSDan Willemsengenerator used to produce it. Generated code contains references to 192*1c12ee1eSDan Willemsen[`protoimpl.EnforceVersion`](https://pkg.go.dev/google.golang.org/protobuf/runtime/protoimpl?tab=doc#EnforceVersion) 193*1c12ee1eSDan Willemsento statically ensure that the generated code and runtime do not drift 194*1c12ee1eSDan Willemsensufficiently far apart. 195*1c12ee1eSDan Willemsen 196*1c12ee1eSDan Willemsen## Historical legacy 197*1c12ee1eSDan Willemsen 198*1c12ee1eSDan WillemsenThis project is the second major revision 199*1c12ee1eSDan Willemsen([released in 2020](https://blog.golang.org/a-new-go-api-for-protocol-buffers)) 200*1c12ee1eSDan Willemsenof the Go protocol buffer API implemented by the 201*1c12ee1eSDan Willemsen[`google.golang.org/protobuf`](https://pkg.go.dev/mod/google.golang.org/protobuf) 202*1c12ee1eSDan Willemsenmodule. The first major version 203*1c12ee1eSDan Willemsen([released publicly in 2010](https://blog.golang.org/third-party-libraries-goprotobuf-and)) 204*1c12ee1eSDan Willemsenis implemented by the 205*1c12ee1eSDan Willemsen[`github.com/golang/protobuf`](https://pkg.go.dev/mod/github.com/golang/protobuf) 206*1c12ee1eSDan Willemsenmodule. 207*1c12ee1eSDan Willemsen 208*1c12ee1eSDan WillemsenThe first version predates the release of Go 1 by several years. It has a long 209*1c12ee1eSDan Willemsenhistory as one of the first core pieces of infrastructure software ever written 210*1c12ee1eSDan Willemsenin Go. As such, the Go protobuf project was one of many pioneers for determining 211*1c12ee1eSDan Willemsenwhat the Go language should even look like and what would eventually be 212*1c12ee1eSDan Willemsenconsidered good design patterns and “idiomatic” Go (by simultaneously being 213*1c12ee1eSDan Willemsenboth positive and negative examples of it). 214*1c12ee1eSDan Willemsen 215*1c12ee1eSDan WillemsenConsider the changing signature of the `proto.Unmarshal` function as an example 216*1c12ee1eSDan Willemsenof Go language and library evolution throughout the life of this project: 217*1c12ee1eSDan Willemsen 218*1c12ee1eSDan Willemsen```go 219*1c12ee1eSDan Willemsen// 2007/09/25 - Conception of Go 220*1c12ee1eSDan Willemsen 221*1c12ee1eSDan Willemsen// 2008/11/12 222*1c12ee1eSDan Willemsenexport func UnMarshal(r io.Read, pb_e reflect.Empty) *os.Error 223*1c12ee1eSDan Willemsen 224*1c12ee1eSDan Willemsen// 2008/11/13 225*1c12ee1eSDan Willemsenexport func UnMarshal(buf *[]byte, pb_e reflect.Empty) *os.Error 226*1c12ee1eSDan Willemsen 227*1c12ee1eSDan Willemsen// 2008/11/24 228*1c12ee1eSDan Willemsenexport func UnMarshal(buf *[]byte, pb_e interface{}) *os.Error 229*1c12ee1eSDan Willemsen 230*1c12ee1eSDan Willemsen// 2008/12/18 231*1c12ee1eSDan Willemsenexport func UnMarshal(buf []byte, pb_e interface{}) *os.Error 232*1c12ee1eSDan Willemsen 233*1c12ee1eSDan Willemsen// 2009/01/20 234*1c12ee1eSDan Willemsenfunc UnMarshal(buf []byte, pb_e interface{}) *os.Error 235*1c12ee1eSDan Willemsen 236*1c12ee1eSDan Willemsen// 2009/04/17 237*1c12ee1eSDan Willemsenfunc UnMarshal(buf []byte, pb_e interface{}) os.Error 238*1c12ee1eSDan Willemsen 239*1c12ee1eSDan Willemsen// 2009/05/22 240*1c12ee1eSDan Willemsenfunc Unmarshal(buf []byte, pb_e interface{}) os.Error 241*1c12ee1eSDan Willemsen 242*1c12ee1eSDan Willemsen// 2011/11/03 243*1c12ee1eSDan Willemsenfunc Unmarshal(buf []byte, pb_e interface{}) error 244*1c12ee1eSDan Willemsen 245*1c12ee1eSDan Willemsen// 2012/03/28 - Release of Go 1 246*1c12ee1eSDan Willemsen 247*1c12ee1eSDan Willemsen// 2012/06/12 248*1c12ee1eSDan Willemsenfunc Unmarshal(buf []byte, pb Message) error 249*1c12ee1eSDan Willemsen``` 250*1c12ee1eSDan Willemsen 251*1c12ee1eSDan WillemsenThese changes demonstrate the difficulty of determining what the right API is 252*1c12ee1eSDan Willemsenfor any new technology. It takes time multiplied by many users to determine what 253*1c12ee1eSDan Willemsenis best; even then, “best” is often still somewhere over the horizon. 254*1c12ee1eSDan Willemsen 255*1c12ee1eSDan WillemsenThe change on June 6th, 2012 added a degree of type-safety to Go protobufs by 256*1c12ee1eSDan Willemsendeclaring a new interface that all protobuf messages were required to implement: 257*1c12ee1eSDan Willemsen 258*1c12ee1eSDan Willemsen```go 259*1c12ee1eSDan Willemsentype Message interface { 260*1c12ee1eSDan Willemsen Reset() 261*1c12ee1eSDan Willemsen String() string 262*1c12ee1eSDan Willemsen ProtoMessage() 263*1c12ee1eSDan Willemsen} 264*1c12ee1eSDan Willemsen``` 265*1c12ee1eSDan Willemsen 266*1c12ee1eSDan WillemsenThis interface reduced the set of types that can be passed to `proto.Unmarshal` 267*1c12ee1eSDan Willemsenfrom the universal set of all possible Go types to those with a special 268*1c12ee1eSDan Willemsen`ProtoMessage` marker method. The intention of this change is to limit the 269*1c12ee1eSDan Willemsenprotobuf API to only operate on protobuf data types (i.e., protobuf messages). 270*1c12ee1eSDan WillemsenFor example, there is no sensible operation if a Go channel were passed to the 271*1c12ee1eSDan Willemsenprotobuf API as a channel cannot be serialized. The restricted interface would 272*1c12ee1eSDan Willemsenprevent that. 273*1c12ee1eSDan Willemsen 274*1c12ee1eSDan WillemsenThis interface does not behaviorally describe what a protobuf message is, but 275*1c12ee1eSDan Willemsenacts as a marker with an undocumented expectation that protobuf messages must be 276*1c12ee1eSDan Willemsena Go struct with a specific layout of fields with formatted tags. This 277*1c12ee1eSDan Willemsenexpectation is not statically enforced by the Go language, for it is an 278*1c12ee1eSDan Willemsenimplementation detail checked dynamically at runtime using Go reflection. Back 279*1c12ee1eSDan Willemsenin 2012, the only types with this marker were those generated by 280*1c12ee1eSDan Willemsen`protoc-gen-go`. Since `protoc-gen-go` would always generate messages with the 281*1c12ee1eSDan Willemsenproper layout of fields, this was deemed an acceptable and dramatic improvement 282*1c12ee1eSDan Willemsenover `interface{}`. 283*1c12ee1eSDan Willemsen 284*1c12ee1eSDan WillemsenOver the next 10 years, 285*1c12ee1eSDan Willemsen[use of Go would skyrocket](https://blog.golang.org/10years) and use of 286*1c12ee1eSDan Willemsenprotobufs in Go would skyrocket as well. With increased popularity also came 287*1c12ee1eSDan Willemsenmore diverse usages and requirements for Go protobufs and an increased number of 288*1c12ee1eSDan Willemsencustom `proto.Message` implementations that were not generated by 289*1c12ee1eSDan Willemsen`protoc-gen-go`. 290*1c12ee1eSDan Willemsen 291*1c12ee1eSDan WillemsenThe increasingly diverse ecosystem of Go types implementing the `proto.Message` 292*1c12ee1eSDan Willemseninterface led to incompatibilities, which often occurred when: 293*1c12ee1eSDan Willemsen 294*1c12ee1eSDan Willemsen* **Passing custom `proto.Message` types to the protobuf APIs**: A concrete 295*1c12ee1eSDan Willemsen message implementation might work with some top-level functions (e.g., 296*1c12ee1eSDan Willemsen `proto.Marshal`), but cause others (e.g., `proto.Equal`) to choke and panic. 297*1c12ee1eSDan Willemsen This occurs because the type only had partial support for being an actual 298*1c12ee1eSDan Willemsen message by only implementing the `proto.Marshaler` interface or having 299*1c12ee1eSDan Willemsen malformed struct field tags that happened to work with one function, but not 300*1c12ee1eSDan Willemsen another. 301*1c12ee1eSDan Willemsen 302*1c12ee1eSDan Willemsen* **Using Go reflection on any `proto.Message` types**: A common desire is to 303*1c12ee1eSDan Willemsen write general-purpose code that operates on any protobuf message. For 304*1c12ee1eSDan Willemsen example, a microservice might want to populate a `trace_id` field if it is 305*1c12ee1eSDan Willemsen present in a message. To accomplish this, one would use Go reflection to 306*1c12ee1eSDan Willemsen introspect the message type, and assume it were a pointer to a Go struct 307*1c12ee1eSDan Willemsen with a field named `TraceId` (as would be commonly produced by 308*1c12ee1eSDan Willemsen `protoc-gen-go`). If the concrete message type did not match this 309*1c12ee1eSDan Willemsen expectation, it either failed to work or even resulted in a panic. Such was 310*1c12ee1eSDan Willemsen the case for concrete message types that might be backed by a Go map instead 311*1c12ee1eSDan Willemsen of a Go struct. 312*1c12ee1eSDan Willemsen 313*1c12ee1eSDan WillemsenBoth of these issues are solved by following the idiom that _interfaces should 314*1c12ee1eSDan Willemsendescribe behavior, not data_. This means that the interface itself should 315*1c12ee1eSDan Willemsenprovide sufficient functionality through its methods that users can introspect 316*1c12ee1eSDan Willemsenand interact with all aspects of a protobuf message through a principled API. 317*1c12ee1eSDan WillemsenThis feature is called _protobuf reflection_. Just as how Go reflection provides 318*1c12ee1eSDan Willemsenan API for programmatically interacting with any arbitrary Go value, protobuf 319*1c12ee1eSDan Willemsenreflection provides an API for programmatically interacting with any arbitrary 320*1c12ee1eSDan Willemsenprotobuf message. 321*1c12ee1eSDan Willemsen 322*1c12ee1eSDan WillemsenSince an interface cannot be extended in a backwards compatible way, this 323*1c12ee1eSDan Willemsensuggested the need for a new major version that defines a new `proto.Message` 324*1c12ee1eSDan Willemseninterface: 325*1c12ee1eSDan Willemsen 326*1c12ee1eSDan Willemsen```go 327*1c12ee1eSDan Willemsentype Message interface { 328*1c12ee1eSDan Willemsen ProtoReflect() protoreflect.Message 329*1c12ee1eSDan Willemsen} 330*1c12ee1eSDan Willemsen``` 331*1c12ee1eSDan Willemsen 332*1c12ee1eSDan WillemsenThe new 333*1c12ee1eSDan Willemsen[`proto.Message`](https://pkg.go.dev/google.golang.org/protobuf/proto?tab=doc#Message) 334*1c12ee1eSDan Willemseninterface contains a single `ProtoReflect` method that returns a 335*1c12ee1eSDan Willemsen[`protoreflect.Message`](https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect?tab=doc#Message), 336*1c12ee1eSDan Willemsenwhich is a reflective view over a protobuf message. In addition to making a 337*1c12ee1eSDan Willemsenbreaking change to the `proto.Message` interface, we took this opportunity to 338*1c12ee1eSDan Willemsencleanup the supporting functionality that operate on a `proto.Message`, split up 339*1c12ee1eSDan Willemsencomplicated functionality apart into manageable packages, and to hide 340*1c12ee1eSDan Willemsenimplementation details away from the public API. 341*1c12ee1eSDan Willemsen 342*1c12ee1eSDan WillemsenThe goal for this major revision is to improve upon all the benefits of, while 343*1c12ee1eSDan Willemsenaddressing all the shortcomings of the old API. We hope that it will serve the 344*1c12ee1eSDan WillemsenGo ecosystem well for the next 10 years and beyond. 345