golang / protobuf

Go support for Google's protocol buffers
BSD 3-Clause "New" or "Revised" License
9.64k stars 1.58k forks source link

How to properly define protobuf `oneof` fields? #1599

Closed talksik closed 3 months ago

talksik commented 3 months ago

Supposed I started with this with the idea that I can keep adding fields to the oneof.

message Block {
  string id = 1;
  User initiator = 2;
  repeated User receivers = 3;
  google.protobuf.Timestamp created_at = 4;
  BlockType type = 5;
  // whether or not it was "seen" by user
  bool is_processed = 6;

  oneof data {
    VoiceClipBlockData voice_clip = 7;
    // CAN ADD HERE...
  }
}

So that when we want to add, we can do the following:

message Block {
  string id = 1;
  User initiator = 2;
  repeated User receivers = 3;
  google.protobuf.Timestamp created_at = 4;
  BlockType type = 5;
  // whether or not it was "seen" by user
  bool is_processed = 6;

  oneof data {
    VoiceClipBlockData voice_clip = 7;
    VideoClipBlockData video_clip = 8;
  }
}

What if I want to add a field outside the oneof block. For instance, I want to add updated_at to the block top level.

message Block {
  string id = 1;
  User initiator = 2;
  repeated User receivers = 3;
  google.protobuf.Timestamp created_at = 4;
  BlockType type = 5;
  // whether or not it was "seen" by user
  bool is_processed = 6;

  oneof data {
    VoiceClipBlockData voice_clip = 7;
    VideoClipBlockData video_clip = 8;
  }

  google.protobuf.Timestamp updated_at = 9;
}

This ^ creates a bit of a pickle. Now I can't freely add to the oneof. I believe I can add to the oneof field from number 10, but that seems like bad practice/don't even know if it's possible.

I could also create another message TopLevelProperties {} so that those can continue to grow:

message Block {
  TopLevelProperties properties = 1;

  oneof data {
    VoiceClipBlockData voice_clip = 2;
    VideoClipBlockData video_clip = 3;
  }
}

But this seems like a workaround and I feel like I must be missing some design.

puellanivis commented 3 months ago

I believe I can add to the oneof field from number 10, but that seems like bad practice/don't even know if it's possible.

This is not only possible, this is the correct way to add another field to the oneof if 9 is already used. There is no requirement that fields composing a oneof be sequential, or even near each other in field numbers.

talksik commented 3 months ago

Thanks @puellanivis

Appreciate the clarity! 🙏