Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize/deserialize a protobuf message that uses 'oneof' with ScalaPB?

I'm using ScalaPB to compile my Scala case classes for serializing my protobuf messages.

I have a .proto file with the following messages:

message WrapperMessage {
    oneof msg {
        Login login = 1;
        Register register = 2;
    }
}

message Login {
    required string email = 1;
    required string password = 2;
}

message Register {
    required string email = 1;
    required string password = 2;
    optional string firstName = 3;
    optional string lastName = 4;
}

How do I create my WrapperMessage knowing that I want to put a Login message inside the msg?

  val login = Login(email = "[email protected]", password = "testpass")
  val wrapperMessage = WrapperMessage(???)
  val wrapperMessageBytes = wrapperMessage.toByteArray

Let's say now that I am receiving a WrapperMessage over the wire; how do I deserialize the message using ScalaPB case class methods?

like image 481
Edward Maxedon Avatar asked Mar 30 '16 20:03

Edward Maxedon


People also ask

How do you serialize an object in Protobuf?

Protobuf is create for serialize purpose so I recommend you no need to serialize it again to a Serializable or Parcelable object. Instead of, serialize it to byte array and put byte array to to bundle.

What is oneof in Protobuf?

Protocol Buffer (Protobuf) provides two simpler options for dealing with values that might be of more than one type. The Any type can represent any known Protobuf message type. And you can use the oneof keyword to specify that only one of a range of fields can be set in any message.

What is ScalaPB?

ScalaPB is a protocol buffer compiler ( protoc ) plugin for Scala. It will generate Scala case classes, parsers and serializers for your protocol buffers. ScalaPB generates case classes that can co-exist in the same project alongside the Java-generated code for ProtocolBuffer.

What is the use of Google Protobuf?

Protocol Buffers (Protobuf) is a free and open-source cross-platform data format used to serialize structured data. It is useful in developing programs to communicate with each other over a network or for storing data.


2 Answers

ScalaPB has documentation which clearly provides examples for the questions I am asking. In this answer I tailor the examples provided on ScalaPB towards my question.

To initialize a message with oneof:

val login = Login(email = "[email protected]", password = "testpass")
val wrapperMessage = WrapperMessage().withLogin(login)

To match against a message's oneof field:

wrapperMessage.msg match {
  case Msg.Login(l) =>  // handle l
  case Msg.Register(r) =>  // handle r
  case Msg.Empty =>  // handle exceptional case...
}
like image 197
Edward Maxedon Avatar answered Oct 17 '22 12:10

Edward Maxedon


You should be able to initialize WrapperMessage with an empty constructor and call .set_login(login)

You would deserialize to WrapperMessage and pattern match on message.WhichOneof which returns either "login" or "register". Then you would call the accessor on that specific message (ie. message.login).

like image 1
kliew Avatar answered Oct 17 '22 12:10

kliew