Victor Cui
Victor Cui

Reputation: 1705

Oneof kind vs Enum in protobuf

What's the difference between using an Enum and a oneof kind in protobuf3? As far as I can tell, an Enum restricts the field to be one of a predefined set of values, but so does the oneof kind.

Upvotes: 13

Views: 9299

Answers (1)

Bart
Bart

Reputation: 1580

Enums are named numbers. You define the names in the enum definition and assign them a value. An enum should always have the value zero it it's set.

enum State {
  A = 0;
  B = 1;
  C = 2;
}

Next you can use this enum in any of your message

message Update {
  State currentState = 1;
  State previousState = 2;
}

A oneof is something very different. It allows you to send different types but only allocate limited memory for them. This as you can only set one of those types at a time. This is similar to an union in C/C++ or a std::variant as of C++17.

Take this example in which we have a message, a integer and double defined in our oneof.

// The message in our oneof
message someMsg {
  // Multiple fields
}

// The message holding our oneof
message msgWithOneof {

  oneof theOneof {
    someMsg msg     = 1;
    int32   counter = 2;
    double  value   = 3;
  }
  // Feel free to add more fields her of before the oneof
}

You are only able to set msg, counter or value at one time. If you set another this will clear the other field.

Assuming an C/C++ implementation the largest field will determine the amount of memory allocated. Say someMsg is the largest, setting a integer or double will not be a problem as they fit in the same space. If you not use a oneof the total memory allocated would be the sum of sizeof(someMsg) + sizeof(int32) + sizeof(double).

There is some overhead to keep track which field has been set. In the google C++ implementation this is a bit in the presence variable. This is similar to fields which are marked optional.

Upvotes: 5

Related Questions