Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using structs in oneOf field in Protocol Buffers v3 via Go

So trying to using Protocol Buffers v3 and Go together (new to both).

example.proto

syntax = "proto3";

package test;

import "google/protobuf/timestamp.proto";

message Metadata {
    uint64 userID = 2;
    google.protobuf.Timestamp time= 3; 
}

//SignOff when user logs out of Glory
message SignOff {
    Metadata metadata =1;
}

//SignOn when user logs into Glory
message SignOn {
    Metadata metadata =1;
}

message EventWrapper {
    oneof event {
        SignOff signOff = 1;
        SignOn signOn = 2;
    }
}

Converting with protoc and using in Go

now, _ := ptypes.TimestampProto(time.Now())
event := &pb_test.EventWrapper{
    Event: &pb_test.EventWrapper_SignOn{
        SignOn: &pb_test.SignOn{
            Metadata: &pb_test.Metadata{
                UserID: 1234,
                Time:   now,
            },
        },
    },
}
protoBytes, err := proto.Marshal(event)
if err != nil {
    log.Fatal(err)
}
log.Println(len(protoBytes) == 0)

jsonBytes, _ = json.MarshalIndent(event, "", "\t")
log.Println(string(jsonBytes))

The output shows the JSON is right but the protobuf encoded byte array is empty.

{
    "Event": {
        "SignOn": {
            "metadata": {
                "userID": 1234,
                "time": {
                    "seconds": 1491143507,
                    "nanos": 654053400
                }
            }
        }
    }
}

The intent is the have a array of these (repeated *EventWrapper) to send along the wire via gRPC, but the individual ones don't work at the moment. The protobuf Language Guide doesn't say anything about structs not being allowed. Is there something I'm missing?

like image 957
Delaney Avatar asked Oct 29 '22 09:10

Delaney


1 Answers

Nothing in the Protocol Buffer documentation indicates oneof cannot be structs, and in fact the example generates structs for a union field.

I recommend using gogo, which I have personally used for previous commercial projects. Specifically, use protoc-gen-gogoslick

See this section for installing the necessary packages, then run the following for your project

protoc --gogoslick_out=Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types:. example.proto
like image 69
Stuart Carnie Avatar answered Nov 10 '22 13:11

Stuart Carnie