mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-24 14:00:19 +00:00
284 lines
11 KiB
Markdown
284 lines
11 KiB
Markdown
# Go support for Protocol Buffers
|
|
|
|
[![Build Status](https://travis-ci.org/golang/protobuf.svg?branch=master)](https://travis-ci.org/golang/protobuf)
|
|
[![GoDoc](https://godoc.org/github.com/golang/protobuf?status.svg)](https://godoc.org/github.com/golang/protobuf)
|
|
|
|
Google's data interchange format.
|
|
Copyright 2010 The Go Authors.
|
|
https://github.com/golang/protobuf
|
|
|
|
This package and the code it generates requires at least Go 1.6.
|
|
|
|
This software implements Go bindings for protocol buffers. For
|
|
information about protocol buffers themselves, see
|
|
https://developers.google.com/protocol-buffers/
|
|
|
|
## Installation ##
|
|
|
|
To use this software, you must:
|
|
- Install the standard C++ implementation of protocol buffers from
|
|
https://developers.google.com/protocol-buffers/
|
|
- Of course, install the Go compiler and tools from
|
|
https://golang.org/
|
|
See
|
|
https://golang.org/doc/install
|
|
for details or, if you are using gccgo, follow the instructions at
|
|
https://golang.org/doc/install/gccgo
|
|
- Grab the code from the repository and install the proto package.
|
|
The simplest way is to run `go get -u github.com/golang/protobuf/protoc-gen-go`.
|
|
The compiler plugin, protoc-gen-go, will be installed in $GOBIN,
|
|
defaulting to $GOPATH/bin. It must be in your $PATH for the protocol
|
|
compiler, protoc, to find it.
|
|
|
|
This software has two parts: a 'protocol compiler plugin' that
|
|
generates Go source files that, once compiled, can access and manage
|
|
protocol buffers; and a library that implements run-time support for
|
|
encoding (marshaling), decoding (unmarshaling), and accessing protocol
|
|
buffers.
|
|
|
|
There is support for gRPC in Go using protocol buffers.
|
|
See the note at the bottom of this file for details.
|
|
|
|
There are no insertion points in the plugin.
|
|
|
|
|
|
## Using protocol buffers with Go ##
|
|
|
|
Once the software is installed, there are two steps to using it.
|
|
First you must compile the protocol buffer definitions and then import
|
|
them, with the support library, into your program.
|
|
|
|
To compile the protocol buffer definition, run protoc with the --go_out
|
|
parameter set to the directory you want to output the Go code to.
|
|
|
|
protoc --go_out=. *.proto
|
|
|
|
The generated files will be suffixed .pb.go. See the Test code below
|
|
for an example using such a file.
|
|
|
|
## Packages and input paths ##
|
|
|
|
The protocol buffer language has a concept of "packages" which does not
|
|
correspond well to the Go notion of packages. In generated Go code,
|
|
each source `.proto` file is associated with a single Go package. The
|
|
name and import path for this package is specified with the `go_package`
|
|
proto option:
|
|
|
|
option go_package = "github.com/golang/protobuf/ptypes/any";
|
|
|
|
The protocol buffer compiler will attempt to derive a package name and
|
|
import path if a `go_package` option is not present, but it is
|
|
best to always specify one explicitly.
|
|
|
|
There is a one-to-one relationship between source `.proto` files and
|
|
generated `.pb.go` files, but any number of `.pb.go` files may be
|
|
contained in the same Go package.
|
|
|
|
The output name of a generated file is produced by replacing the
|
|
`.proto` suffix with `.pb.go` (e.g., `foo.proto` produces `foo.pb.go`).
|
|
However, the output directory is selected in one of two ways. Let
|
|
us say we have `inputs/x.proto` with a `go_package` option of
|
|
`github.com/golang/protobuf/p`. The corresponding output file may
|
|
be:
|
|
|
|
- Relative to the import path:
|
|
|
|
protoc --go_out=. inputs/x.proto
|
|
# writes ./github.com/golang/protobuf/p/x.pb.go
|
|
|
|
(This can work well with `--go_out=$GOPATH`.)
|
|
|
|
- Relative to the input file:
|
|
|
|
protoc --go_out=paths=source_relative:. inputs/x.proto
|
|
# generate ./inputs/x.pb.go
|
|
|
|
## Generated code ##
|
|
|
|
The package comment for the proto library contains text describing
|
|
the interface provided in Go for protocol buffers. Here is an edited
|
|
version.
|
|
|
|
The proto package converts data structures to and from the
|
|
wire format of protocol buffers. It works in concert with the
|
|
Go source code generated for .proto files by the protocol compiler.
|
|
|
|
A summary of the properties of the protocol buffer interface
|
|
for a protocol buffer variable v:
|
|
|
|
- Names are turned from camel_case to CamelCase for export.
|
|
- There are no methods on v to set fields; just treat
|
|
them as structure fields.
|
|
- There are getters that return a field's value if set,
|
|
and return the field's default value if unset.
|
|
The getters work even if the receiver is a nil message.
|
|
- The zero value for a struct is its correct initialization state.
|
|
All desired fields must be set before marshaling.
|
|
- A Reset() method will restore a protobuf struct to its zero state.
|
|
- Non-repeated fields are pointers to the values; nil means unset.
|
|
That is, optional or required field int32 f becomes F *int32.
|
|
- Repeated fields are slices.
|
|
- Helper functions are available to aid the setting of fields.
|
|
Helpers for getting values are superseded by the
|
|
GetFoo methods and their use is deprecated.
|
|
msg.Foo = proto.String("hello") // set field
|
|
- Constants are defined to hold the default values of all fields that
|
|
have them. They have the form Default_StructName_FieldName.
|
|
Because the getter methods handle defaulted values,
|
|
direct use of these constants should be rare.
|
|
- Enums are given type names and maps from names to values.
|
|
Enum values are prefixed with the enum's type name. Enum types have
|
|
a String method, and a Enum method to assist in message construction.
|
|
- Nested groups and enums have type names prefixed with the name of
|
|
the surrounding message type.
|
|
- Extensions are given descriptor names that start with E_,
|
|
followed by an underscore-delimited list of the nested messages
|
|
that contain it (if any) followed by the CamelCased name of the
|
|
extension field itself. HasExtension, ClearExtension, GetExtension
|
|
and SetExtension are functions for manipulating extensions.
|
|
- Oneof field sets are given a single field in their message,
|
|
with distinguished wrapper types for each possible field value.
|
|
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
|
|
|
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
|
|
|
- Non-repeated fields of non-message type are values instead of pointers.
|
|
- Enum types do not get an Enum method.
|
|
|
|
Consider file test.proto, containing
|
|
|
|
```proto
|
|
syntax = "proto2";
|
|
package example;
|
|
|
|
enum FOO { X = 17; };
|
|
|
|
message Test {
|
|
required string label = 1;
|
|
optional int32 type = 2 [default=77];
|
|
repeated int64 reps = 3;
|
|
optional group OptionalGroup = 4 {
|
|
required string RequiredField = 5;
|
|
}
|
|
}
|
|
```
|
|
|
|
To create and play with a Test object from the example package,
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"log"
|
|
|
|
"github.com/golang/protobuf/proto"
|
|
"path/to/example"
|
|
)
|
|
|
|
func main() {
|
|
test := &example.Test {
|
|
Label: proto.String("hello"),
|
|
Type: proto.Int32(17),
|
|
Reps: []int64{1, 2, 3},
|
|
Optionalgroup: &example.Test_OptionalGroup {
|
|
RequiredField: proto.String("good bye"),
|
|
},
|
|
}
|
|
data, err := proto.Marshal(test)
|
|
if err != nil {
|
|
log.Fatal("marshaling error: ", err)
|
|
}
|
|
newTest := &example.Test{}
|
|
err = proto.Unmarshal(data, newTest)
|
|
if err != nil {
|
|
log.Fatal("unmarshaling error: ", err)
|
|
}
|
|
// Now test and newTest contain the same data.
|
|
if test.GetLabel() != newTest.GetLabel() {
|
|
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
|
|
}
|
|
// etc.
|
|
}
|
|
```
|
|
|
|
## Parameters ##
|
|
|
|
To pass extra parameters to the plugin, use a comma-separated
|
|
parameter list separated from the output directory by a colon:
|
|
|
|
protoc --go_out=plugins=grpc,import_path=mypackage:. *.proto
|
|
|
|
- `paths=(import | source_relative)` - specifies how the paths of
|
|
generated files are structured. See the "Packages and imports paths"
|
|
section above. The default is `import`.
|
|
- `plugins=plugin1+plugin2` - specifies the list of sub-plugins to
|
|
load. The only plugin in this repo is `grpc`.
|
|
- `Mfoo/bar.proto=quux/shme` - declares that foo/bar.proto is
|
|
associated with Go package quux/shme. This is subject to the
|
|
import_prefix parameter.
|
|
|
|
The following parameters are deprecated and should not be used:
|
|
|
|
- `import_prefix=xxx` - a prefix that is added onto the beginning of
|
|
all imports.
|
|
- `import_path=foo/bar` - used as the package if no input files
|
|
declare `go_package`. If it contains slashes, everything up to the
|
|
rightmost slash is ignored.
|
|
|
|
## gRPC Support ##
|
|
|
|
If a proto file specifies RPC services, protoc-gen-go can be instructed to
|
|
generate code compatible with gRPC (http://www.grpc.io/). To do this, pass
|
|
the `plugins` parameter to protoc-gen-go; the usual way is to insert it into
|
|
the --go_out argument to protoc:
|
|
|
|
protoc --go_out=plugins=grpc:. *.proto
|
|
|
|
## Compatibility ##
|
|
|
|
The library and the generated code are expected to be stable over time.
|
|
However, we reserve the right to make breaking changes without notice for the
|
|
following reasons:
|
|
|
|
- Security. A security issue in the specification or implementation may come to
|
|
light whose resolution requires breaking compatibility. We reserve the right
|
|
to address such security issues.
|
|
- Unspecified behavior. There are some aspects of the Protocol Buffers
|
|
specification that are undefined. Programs that depend on such unspecified
|
|
behavior may break in future releases.
|
|
- Specification errors or changes. If it becomes necessary to address an
|
|
inconsistency, incompleteness, or change in the Protocol Buffers
|
|
specification, resolving the issue could affect the meaning or legality of
|
|
existing programs. We reserve the right to address such issues, including
|
|
updating the implementations.
|
|
- Bugs. If the library has a bug that violates the specification, a program
|
|
that depends on the buggy behavior may break if the bug is fixed. We reserve
|
|
the right to fix such bugs.
|
|
- Adding methods or fields to generated structs. These may conflict with field
|
|
names that already exist in a schema, causing applications to break. When the
|
|
code generator encounters a field in the schema that would collide with a
|
|
generated field or method name, the code generator will append an underscore
|
|
to the generated field or method name.
|
|
- Adding, removing, or changing methods or fields in generated structs that
|
|
start with `XXX`. These parts of the generated code are exported out of
|
|
necessity, but should not be considered part of the public API.
|
|
- Adding, removing, or changing unexported symbols in generated code.
|
|
|
|
Any breaking changes outside of these will be announced 6 months in advance to
|
|
protobuf@googlegroups.com.
|
|
|
|
You should, whenever possible, use generated code created by the `protoc-gen-go`
|
|
tool built at the same commit as the `proto` package. The `proto` package
|
|
declares package-level constants in the form `ProtoPackageIsVersionX`.
|
|
Application code and generated code may depend on one of these constants to
|
|
ensure that compilation will fail if the available version of the proto library
|
|
is too old. Whenever we make a change to the generated code that requires newer
|
|
library support, in the same commit we will increment the version number of the
|
|
generated code and declare a new package-level constant whose name incorporates
|
|
the latest version number. Removing a compatibility constant is considered a
|
|
breaking change and would be subject to the announcement policy stated above.
|
|
|
|
The `protoc-gen-go/generator` package exposes a plugin interface,
|
|
which is used by the gRPC code generation. This interface is not
|
|
supported and is subject to incompatible changes without notice.
|