1

I have a protobuf file in which I define multiple messages which all inherit the same trait (using option (scalapb.message).extends = "Event"; inside of message definition).

I would like to create a new message called MultiEvent which may contain sequence of any of the messages inherited from Event.

Event is defined as simple trait Event in scala code.

The idea is to be able to send special message which contains multiple of messages at once.

syntax = "proto3";

import "scalapb/scalapb.proto";

package com.some.package;

message A {
  option (scalapb.message).extends = "Event";
  string name = 1;
}

message B {
  option (scalapb.message).extends = "Event";
  string field = 1;
}

message C {
  option (scalapb.message).extends = "Event";
  string otherField = 1;
}

message MultiEvent {
  option (scalapb.message).extends = "Event";
  repeated Event seq = 1; // this line is problematic
}

I got the error: "Event" is not defined.. Ideally from the code the field would be a simple Seq, which repeated provides, but it works only with scalar types. I have found on internet that Any may be able to accomplish what I want, but I get errors when try to use it.

What is the usual way of solving problems like this? Enum? Conversion?

Thanks.

Darko
  • 113
  • 7

1 Answers1

1

The usual way is oneof (in Protocol Buffers 3). repeated oneof is illegal:

Repeated oneof was in the initial proposal but as we later found out, there were lots many complicated corner cases in wire and API. We decided not to add repeated for oneof.

You can always define a message which wraps a oneof and have a repeated field of that message instead.

so

message Event {
  oneof sealed_value {
    A a = 1;
    B b = 2;
    C c = 3;
    ...
  }
}

and then repeated Event as you currently have.

Using sealed_value as the name enables ScalaPB's sealed oneof support.

Community
  • 1
  • 1
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • I see your point, but than in the code, I need to check a, b and c which holds the value. Looks like it adds one more level of indirection... Maybe there is no better way of doing it, dough. :-/ – Darko Aug 14 '19 at 14:30
  • 1
    @Darko - the generated code for sealed oneofs doesn't add extra indirection (the name `sealed_value` must be used). You will end up with the API that I think you will like. If there is something that doesn't work for you in the generated code, can you be more cleasr about what it is? Not sure what you mean by "I need to check a, b and c which holds the value". See https://scalapb.github.io/sealed-oneofs.html . – thesamet Aug 15 '19 at 17:28
  • You are right, at first I was examining the generated code and got such idea. – Darko Aug 16 '19 at 19:37