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