jack Sun
jack Sun

Reputation: 21

How to set/get protobuf's extension field in Go?

I am a Go language developer. Our team chose to use protocol buffers to transform data. I chose this protobuf package: https://github.com/golang/protobuf. However, this package has no method to handle the extensions field in a protocol buffer. I have only found this code in the class file generated by protoc:

var E_Height = &proto.ExtensionDesc{
    ExtendedType:  (*Person)(nil),
    ExtensionType: (*int32)(nil),
    Field:         110,
    Name:          "eg.Height",
    Tag:           "varint,110,opt",
}

func init() {
    proto.RegisterExtension(E_Height)
}

So, how can I set/get the extensions field in Go?

Upvotes: 2

Views: 9516

Answers (2)

Alan E
Alan E

Reputation: 400

From: https://developers.google.com/protocol-buffers/docs/reference/go-generated#extensions

For example, given the following definition:

extend Foo {
  optional int32 singular_int32 = 1;
  repeated bytes repeated_string = 2;
  optional Bar repeated_message = 3;
}

Extension values may be accessed as:

m := &somepb.Foo{}
proto.SetExtension(m, extpb.E_SingularInt32, int32(1))
proto.SetExtension(m, extpb.E_RepeatedString, []string{"a", "b", "c"})
proto.SetExtension(m, extpb.E_RepeatedMessage, &extpb.Bar{})

v1 := proto.GetExtension(m, extpb.E_SingularInt32).(int32)
v2 := proto.GetExtension(m, extpb.E_RepeatedString).([][]byte)
v3 := proto.GetExtension(m, extpb.E_RepeatedMessage).(*extpb.Bar)

Upvotes: 1

sberry
sberry

Reputation: 131978

Getting the extension...

yourExtendedEvent := &path_to_your_events.Person{}
err := proto.Unmarshal(yourBytes, yourExtendedEvent)
if err != nil {
    // handle error case
}
extendedEvent, extendedError := proto.GetExtension(
    yourExtendedEvent,
    path_to_your_events.E_Height,
)
...

Setting the extension...

yourExtendedEvent := &path_to_your_events.Person{
    Field1: proto.Uint64(1),
    Field2: proto.String("foo"),
}

height := &path_to_your_events.Height {
    Field1: proto.Int64(120),
}

err := proto.SetExtension(
    yourExtendedEvent,
    path_to_your_events.E_Height,
    height,
)

if err != nil {
    // handle error case
}

EDIT

Actually, if I am reading it right, your extension is just a single field (an int32) so I don't know that you actually have a Height type. If not, it might be more like

height := proto.Int32(120)

And then you set the same way with height as a single field rather than as a distinct proto type.

This line

ExtensionType: (*int32)(nil),

Makes me think it will be a single field, whereas our extensions look more like

ExtensionType: (*SomeOtherType)(nil),

This is a good resource TestExtensionsRoundTrip

Upvotes: 2

Related Questions