.proto file is the source of truth for your data schema. It defines messages, enumerations, and services that the Protocol Buffer compiler (protoc) translates into generated code for your target language.
This page walks through every top-level construct you will encounter in a .proto file.
Syntax declaration
Every.proto file should begin with a syntax statement that declares which language version is in use. If the statement is omitted, the compiler defaults to proto2.
syntax statement must appear before any other non-comment, non-whitespace content in the file.
This documentation covers
proto3. proto2 is still supported but new schemas should use proto3 unless you have a specific requirement for proto2 semantics.Package declaration
Thepackage statement prevents name collisions between message types defined in different projects. Package names are dot-separated identifiers that form a namespace.
- C++: nested namespaces matching each component (e.g.,
tutorial::) - Java: used as the Java package unless overridden by
java_package - Go: the last component of the package becomes the Go package name unless overridden by
go_package - Python: package names have no effect on the generated module structure
addressbook.proto example uses:
Import statements
Useimport to bring in definitions from other .proto files.
protoc resolves imports relative to the directories specified with -I / --proto_path flags. If no -I flag is given, the current directory is used.
Public imports
Apublic import re-exports all definitions to any file that imports the current file:
Weak imports
Aweak import signals that the dependency is optional — if the imported file is not found at compile time, the import is silently ignored. This feature is intended for internal migration use and should not be used in new schemas.
Message definitions
Amessage is the primary container for structured data. Each field inside a message has a type, a name, and a unique field number.
Nested messages
Messages can be defined inside other messages. Nested definitions are scoped to the enclosing message:Reserved fields
When you remove a field, reserve its number (and optionally its name) to prevent future definitions from accidentally reusing it:Enum definitions
Enumerations define a fixed set of named integer constants. The first value in an enum must be zero.Service definitions
Services declare RPC (Remote Procedure Call) interfaces for use with gRPC. Eachrpc method specifies its request and response message types.
Streaming RPCs
gRPC supports four RPC types:- Unary
- Server streaming
- Client streaming
- Bidirectional streaming
Options
Options customise compiler behaviour and generated code without changing the semantics of the proto definition itself. They are specified using theoption keyword.
File-level options
File-level options apply to the whole file and must appear at the top level (outside any message or service block).| Option | Effect |
|---|---|
java_package | Java package for generated classes |
java_outer_classname | Outer class name wrapping all generated Java classes |
java_multiple_files | Generate one .java file per top-level type |
go_package | Go import path for the generated package |
csharp_namespace | C# namespace for generated classes |
objc_class_prefix | Prefix for Objective-C class names |
optimize_for | SPEED, CODE_SIZE, or LITE_RUNTIME |
cc_enable_arenas | Enable arena allocation for C++ |
Message-level options
Message-level options appear inside a message body:Field-level options
Field-level options appear after the field definition:packed option (default true in proto3 for numeric types) controls whether repeated scalar fields use the packed encoding format.
Complete example
The following is the completeaddressbook.proto from the official protobuf examples repository, showing all the constructs described on this page working together: