Skip to content

Instantly share code, notes, and snippets.

@florianleibert
Created August 20, 2012 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save florianleibert/3406865 to your computer and use it in GitHub Desktop.
Save florianleibert/3406865 to your computer and use it in GitHub Desktop.
Dynamic protobuf builder
object Protobufs {
def newBuilder() : Builder = {
return new Builder()
}
class Builder {
private val desBuilder : DescriptorProtos.DescriptorProto.Builder = DescriptorProtos.DescriptorProto.newBuilder()
private val values = new mutable.HashMap[String, Any]()
private var i = 1
private var canBuild = true
def addField[T](fieldName : String, fieldValue : T, fieldType : FieldDescriptorProto.Type) : Builder = {
require(canBuild, "Builder is no longer valid!")
val fieldBuilder = DescriptorProtos.FieldDescriptorProto.newBuilder()
.setName(fieldName).setNumber(i).setType(fieldType)
desBuilder.addField(fieldBuilder.build())
values.put(fieldName, fieldValue)
i+=1
return this
}
def build(messageName : String) : Message = {
desBuilder.setName(messageName)
val dsc = desBuilder.build()
val fileDescP = DescriptorProtos.FileDescriptorProto.newBuilder().addMessageType(dsc).build()
val fileDecs = new Array[Descriptors.FileDescriptor](0)
val dynamicDescriptor = Descriptors.FileDescriptor.buildFrom(fileDescP, fileDecs)
val msgDescriptor = dynamicDescriptor.findMessageTypeByName(messageName)
val dmBuilder = DynamicMessage.newBuilder(msgDescriptor)
values.foreach({ case (key, value) =>
dmBuilder.setField(msgDescriptor.findFieldByName(key), value)
})
canBuild = false
return dmBuilder.build()
}
}
def main(args : Array[String]) {
val msg = Protobufs.newBuilder()
.addField("foo", "bar", DescriptorProtos.FieldDescriptorProto.Type.TYPE_STRING)
.addField("foo2", "bar", DescriptorProtos.FieldDescriptorProto.Type.TYPE_STRING)
.addField("foo3", "bar", DescriptorProtos.FieldDescriptorProto.Type.TYPE_STRING).build("TestMessage")
println(msg)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment