Use the official protoc compiler with the Go plugin (protoc-gen-go) to compile your .proto files into idiomatic Go source code. You typically run this via the go install command to fetch the plugin, then invoke protoc with the --go_out flag to specify the output directory.
First, ensure the Go plugin is installed in your Go binary path. This is a one-time setup step:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
Once installed, generate the code by running protoc with the specific flags for your proto file and output path. The --go_out flag tells the compiler where to place the generated .pb.go files, and --go_opt allows you to configure options like module paths:
protoc --go_out=. --go_opt=paths=source_relative \
--go_opt=Mgoogle/protobuf=google.golang.org/protobuf \
path/to/your/file.proto
The paths=source_relative option is crucial in modern Go projects; it ensures the generated files are written relative to the proto file's location, preserving your module structure automatically. If you are using a Makefile or a build tool, you can wrap this in a simple target:
.PHONY: proto
proto:
protoc --go_out=. --go_opt=paths=source_relative *.proto
After generation, import the resulting package in your Go code. The generated code will contain the message structs and methods you need to marshal and unmarshal data. For example, if your proto file defines a User message, the generated file will provide a User struct and a Marshal function:
import (
"myproject/gen" // The package path where .pb.go was generated
"google.golang.org/protobuf/proto"
)
func main() {
msg := &gen.User{
Name: "Alice",
Id: 123,
}
// Marshal to bytes
data, err := proto.Marshal(msg)
if err != nil {
panic(err)
}
// Unmarshal from bytes
var user gen.User
if err := proto.Unmarshal(data, &user); err != nil {
panic(err)
}
}
If you are using gRPC as well, you must also install and run the protoc-gen-go-grpc plugin alongside the standard Go plugin to generate the server and client stubs. The process is identical, just adding the --go-grpc_out flag to your command. Always verify that your go.mod file includes the google.golang.org/protobuf dependency, as the generated code relies on it.