Protobuf Well-Known Types

Google's standard protobuf library includes many useful well-known types.

Import Path

1import "google/protobuf/any.proto";
2import "google/protobuf/timestamp.proto";
3import "google/protobuf/duration.proto";
4import "google/protobuf/struct.proto";
5import "google/protobuf/wrappers.proto";
6import "google/protobuf/empty.proto";

Any Type

Store any message type dynamically.

Definition

1syntax = "proto3";
2
3import "google/protobuf/any.proto";
4
5message Container {
6    google.protobuf.Any payload = 1;
7}

Usage (Go)

 1import (
 2    "google.golang.org/protobuf/types/known/anypb"
 3)
 4
 5// Pack a message into Any
 6userMsg := &User{Name: "Alice", Age: 30}
 7anyMsg, err := anypb.New(userMsg)
 8if err != nil {
 9    // handle error
10}
11
12container := &Container{Payload: anyMsg}
13
14// Unpack from Any
15var user User
16if err := container.Payload.UnmarshalTo(&user); err != nil {
17    // handle error
18}
19
20// Check type before unpacking
21if container.Payload.MessageIs(&User{}) {
22    var user User
23    container.Payload.UnmarshalTo(&user)
24}

Usage (Python)

 1from google.protobuf import any_pb2
 2
 3# Pack
 4user_msg = User(name="Alice", age=30)
 5any_msg = any_pb2.Any()
 6any_msg.Pack(user_msg)
 7
 8container = Container(payload=any_msg)
 9
10# Unpack
11user = User()
12if container.payload.Is(User.DESCRIPTOR):
13    container.payload.Unpack(user)

Timestamp

Represents a point in time.

Definition

1import "google/protobuf/timestamp.proto";
2
3message Event {
4    string name = 1;
5    google.protobuf.Timestamp created_at = 2;
6    google.protobuf.Timestamp updated_at = 3;
7}

Usage (Go)

 1import (
 2    "time"
 3    "google.golang.org/protobuf/types/known/timestamppb"
 4)
 5
 6// Create from time.Time
 7now := time.Now()
 8ts := timestamppb.New(now)
 9
10event := &Event{
11    Name: "UserLogin",
12    CreatedAt: ts,
13}
14
15// Convert to time.Time
16t := event.CreatedAt.AsTime()
17
18// Check validity
19if event.CreatedAt.IsValid() {
20    // use timestamp
21}

Usage (Python)

 1from google.protobuf.timestamp_pb2 import Timestamp
 2from datetime import datetime
 3
 4# Create from datetime
 5ts = Timestamp()
 6ts.FromDatetime(datetime.now())
 7
 8event = Event(name="UserLogin", created_at=ts)
 9
10# Convert to datetime
11dt = event.created_at.ToDatetime()

Duration

Represents a time span.

Definition

1import "google/protobuf/duration.proto";
2
3message Task {
4    string name = 1;
5    google.protobuf.Duration timeout = 2;
6    google.protobuf.Duration elapsed = 3;
7}

Usage (Go)

 1import (
 2    "time"
 3    "google.golang.org/protobuf/types/known/durationpb"
 4)
 5
 6// Create from time.Duration
 7timeout := 30 * time.Second
 8dur := durationpb.New(timeout)
 9
10task := &Task{
11    Name: "ProcessData",
12    Timeout: dur,
13}
14
15// Convert to time.Duration
16d := task.Timeout.AsDuration()
17
18// Check validity
19if task.Timeout.IsValid() {
20    // use duration
21}

Struct, Value, ListValue

Dynamic JSON-like structures.

Definition

1import "google/protobuf/struct.proto";
2
3message Config {
4    google.protobuf.Struct settings = 1;
5    google.protobuf.Value dynamic_value = 2;
6    google.protobuf.ListValue items = 3;
7}

Usage (Go)

 1import (
 2    "google.golang.org/protobuf/types/known/structpb"
 3)
 4
 5// Create Struct from map
 6settings := map[string]interface{}{
 7    "debug": true,
 8    "timeout": 30,
 9    "hosts": []string{"localhost", "example.com"},
10}
11
12structSettings, err := structpb.NewStruct(settings)
13if err != nil {
14    // handle error
15}
16
17config := &Config{Settings: structSettings}
18
19// Convert back to map
20m := config.Settings.AsMap()
21
22// Create Value
23val, _ := structpb.NewValue("hello")
24numberVal, _ := structpb.NewValue(42)
25boolVal, _ := structpb.NewValue(true)
26
27// Create ListValue
28list, _ := structpb.NewList([]interface{}{"a", "b", "c"})

Wrappers

Nullable primitive types.

Definition

1import "google/protobuf/wrappers.proto";
2
3message User {
4    string name = 1;
5    google.protobuf.Int32Value age = 2;          // nullable int32
6    google.protobuf.StringValue email = 3;       // nullable string
7    google.protobuf.BoolValue verified = 4;      // nullable bool
8    google.protobuf.DoubleValue balance = 5;     // nullable double
9}

Available Wrappers

  • google.protobuf.DoubleValue
  • google.protobuf.FloatValue
  • google.protobuf.Int64Value
  • google.protobuf.UInt64Value
  • google.protobuf.Int32Value
  • google.protobuf.UInt32Value
  • google.protobuf.BoolValue
  • google.protobuf.StringValue
  • google.protobuf.BytesValue

Usage (Go)

 1import (
 2    "google.golang.org/protobuf/types/known/wrapperspb"
 3)
 4
 5// Create with value
 6age := wrapperspb.Int32(30)
 7email := wrapperspb.String("user@example.com")
 8
 9user := &User{
10    Name: "Alice",
11    Age: age,
12    Email: email,
13}
14
15// Check if set (nil = not set)
16if user.Age != nil {
17    fmt.Println("Age:", user.Age.Value)
18}
19
20// Set to nil (unset)
21user.Email = nil

Empty

Represents an empty message (useful for RPCs).

Definition

1import "google/protobuf/empty.proto";
2
3service UserService {
4    rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty);
5    rpc Ping(google.protobuf.Empty) returns (google.protobuf.Empty);
6}

Usage (Go)

 1import (
 2    "google.golang.org/protobuf/types/known/emptypb"
 3)
 4
 5// Return empty
 6func (s *server) DeleteUser(ctx context.Context, req *DeleteUserRequest) (*emptypb.Empty, error) {
 7    // delete user logic
 8    return &emptypb.Empty{}, nil
 9}
10
11// Call with empty
12resp, err := client.Ping(ctx, &emptypb.Empty{})

FieldMask

Specify which fields to update/return.

Definition

1import "google/protobuf/field_mask.proto";
2
3message UpdateUserRequest {
4    User user = 1;
5    google.protobuf.FieldMask update_mask = 2;
6}

Usage (Go)

 1import (
 2    "google.golang.org/protobuf/types/known/fieldmaskpb"
 3)
 4
 5// Create field mask
 6mask, err := fieldmaskpb.New(&User{}, "name", "email")
 7if err != nil {
 8    // handle error
 9}
10
11req := &UpdateUserRequest{
12    User: &User{
13        Name: "Alice",
14        Email: "alice@example.com",
15    },
16    UpdateMask: mask,
17}
18
19// Check if field is in mask
20if mask.IsValid(&User{}) {
21    // mask is valid for User type
22}
23
24// Get paths
25paths := mask.GetPaths() // ["name", "email"]

Quick Reference

TypeImportUse Case
Anygoogle/protobuf/any.protoStore any message type
Timestampgoogle/protobuf/timestamp.protoPoint in time
Durationgoogle/protobuf/duration.protoTime span
Structgoogle/protobuf/struct.protoDynamic JSON-like data
Valuegoogle/protobuf/struct.protoDynamic single value
ListValuegoogle/protobuf/struct.protoDynamic array
Emptygoogle/protobuf/empty.protoEmpty response
FieldMaskgoogle/protobuf/field_mask.protoPartial updates
*Value (wrappers)google/protobuf/wrappers.protoNullable primitives

Best Practices

  1. Use Timestamp for dates - Don't use int64 for timestamps
  2. Use Duration for time spans - Don't use int64 for durations
  3. Use wrappers for optional primitives - Distinguish between zero and unset
  4. Use Any sparingly - Type safety is lost, prefer oneof when possible
  5. Use Empty for void RPCs - Standard way to represent no data
  6. Use FieldMask for updates - Partial updates in REST/gRPC APIs
  7. Use Struct for dynamic data - When schema is unknown at compile time

Common Patterns

Optional Fields (Proto3)

1message User {
2    string name = 1;
3    google.protobuf.Int32Value age = 2;  // optional, can be null
4}

Polymorphic Messages

1message Event {
2    string id = 1;
3    google.protobuf.Timestamp timestamp = 2;
4    google.protobuf.Any payload = 3;  // Can be any event type
5}

Partial Updates

1message UpdateRequest {
2    User user = 1;
3    google.protobuf.FieldMask update_mask = 2;
4}

Dynamic Configuration

1message Config {
2    google.protobuf.Struct settings = 1;  // Arbitrary JSON-like config
3}

Related Snippets