Skip to content
Oliver Schrenk edited this page Jul 26, 2013 · 9 revisions

Compiling .proto files

  $ sbt 
  > run --proto_path=INPUT_DIR --scala_out=OUTPUT_DIR

with

  • --proto_path The directory in which to search for imports. May be specified multiple times; Directories will be searched in order. If not given, the current working directory is used
  • --scala_out Generate Scala source files in this directory (if not specified, current directory is used).

For more details and options

  sbt run --help

Serializing and deserializing a message

Source protobuf file complex.proto transforms into Complex.scala using ScalaBuff. It can be then used like so: MessageTest.scala (actual code is inside the test() method).

Serializing and deserializing multiple messages

The process is the same, except you can use myMessage.writeDelimitedTo(OutputStream) for serializing each message. Then for deserialization use MyMessage.defaultInstance.mergeDelimitedFromStream(InputStream), which will return an Option[MyMessage]: a Some[MyMessage] if another message has been read, or a None if the end of the stream has been reached.

// write a single message
sent.writeDelimitedTo(myOutputStream)

// ...

// read all available messages
val default = ComplexMessage.defaultInstance
val received1 = default.mergeDelimitedFromStream(myInputStream)
received1 foreach { message => /* do something with the message */ }
val received2 = default.mergeDelimitedFromStream(myInputStream)
received2 foreach { message => /* this won't be called since we only wrote 1 message */ }

For a more FP-oriented approach for reading all available messages, try this:

for {
  received <- Stream.continually(default.mergeDelimitedFromStream(myInputStream)).takeWhile { _.isDefined }
  message <- received
} { 
  /* do something with the message */ 
}

Instead of the above, you can also use a "container" message which contains your desired message as a repeated field, which is transformed to a simple Scala collection.