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?
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.
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.
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.
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.
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...
}
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
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With