Skip to content
Browse files

changed message classes to case classes and added copyAndSet(Int, Any)

refactored types in Message.scala cause i just learned what the type keyword does

fixed the set(Int, Any) method for real although i'm debating removing builders entirely
  • Loading branch information...
1 parent f7d8e10 commit d60aa2cdc99d524133319e990e3ab7385a4fcac2 @jeffplaisance committed
View
BIN lib/scala-protobuf_2.8.0-0.1.jar
Binary file not shown.
View
37 src/main/scala/protobuf/Message.scala
@@ -24,34 +24,41 @@ object ByteArrayByteStringImplicits {
}
trait Message {
+ type A <: TypedMessage[A,B]
+ type B <: com.google.protobuf.Message
def get(i:Int):Any
def writeTo(outputStream:OutputStream):Unit
def writeDelimitedTo(outputStream:OutputStream):Unit
- def javaMessage:com.google.protobuf.Message
+ def javaMessage:B
+ def copyAndSet(i:Int, fieldValue:Any):A
}
-trait TypedMessage[A <: com.google.protobuf.Message] extends Message {
- override def javaMessage:A
+trait TypedMessage[C <: TypedMessage[C, D], D <: com.google.protobuf.Message] extends Message {
+ type A = C
+ type B = D
}
trait MessageBuilder {
- def set(i:Int, fieldValue:Option[Any]):Unit
- def build:Message
+ type A <: TypedMessage[A, B]
+ type B <: com.google.protobuf.Message
+ def set(i:Int, fieldValue:Any):Unit
+ def build:A
}
-trait TypedMessageBuilder[A <: TypedMessage[B], B <: com.google.protobuf.Message] extends MessageBuilder {
- override def build:A
+trait TypedMessageBuilder[C <: TypedMessage[C, D], D <: com.google.protobuf.Message] extends MessageBuilder {
+ type A = C
+ type B = D
}
trait MessageParser {
- def parseFrom(inputStream:InputStream):Message
- def parseDelimitedFrom(inputStream:InputStream):Message
- def javaToScala(message:com.google.protobuf.Message):Message
+ type A <: TypedMessage[A, B]
+ type B <: com.google.protobuf.Message
+ def parseFrom(inputStream:InputStream):A
+ def parseDelimitedFrom(inputStream:InputStream):A
+ def javaToScala(b:B):A
}
-trait TypedMessageParser[A <: TypedMessage[B], B <: com.google.protobuf.Message] extends MessageParser {
- override def parseFrom(inputStream:InputStream):A
- override def parseDelimitedFrom(inputStream:InputStream):A
- def javaToScala(message:B):A
- override def javaToScala(message:com.google.protobuf.Message):Message = javaToScala(message.asInstanceOf[B])
+trait TypedMessageParser[C <: TypedMessage[C, D], D <: com.google.protobuf.Message] extends MessageParser {
+ type A = C
+ type B = D
}
View
30 src/main/scala/protobuf/compiler/ScalaProtoWrapperGenerator.scala
@@ -71,27 +71,28 @@ object ScalaProtoWrapperGenerator {
val requiredFields = fields.filter(field => field.isRequired)
val requiredFieldTypes = getFieldTypes(requiredFields, javaClass)
- val requiredFieldVals = requiredFields.zip(requiredFieldTypes.unzip._1).map(x => "val "+x._1.getName+":"+x._2)
- val requiredFieldVars = requiredFields.zip(requiredFieldTypes.unzip._1).map(x => "var "+x._1.getName+":"+x._2)
+ val requiredFieldDecls = requiredFields.zip(requiredFieldTypes.unzip._1).map(x => x._1.getName+":"+x._2)
+ val requiredFieldVars = requiredFieldDecls.map(x => "var "+x)
val optionalFields = fields.filter(field => field.isOptional)
val optionalFieldTypes = getFieldTypes(optionalFields, javaClass)
- val optionalFieldVals = optionalFields.zip(optionalFieldTypes.unzip._1).map(x => "val "+x._1.getName+":Option["+x._2+"]")
- val optionalFieldVars = optionalFields.zip(optionalFieldTypes.unzip._1).map(x => "var "+x._1.getName+":Option["+x._2+"] = None")
+ val optionalFieldDecls = optionalFields.zip(optionalFieldTypes.unzip._1).map(x => x._1.getName+":Option["+x._2+"]")
+ val optionalFieldDefaults = optionalFieldDecls.map(x => x+" = None")
+ val optionalFieldVars = optionalFieldDefaults.map(x => "var "+x)
val repeatedFields = fields.filter(field => field.isRepeated)
val repeatedFieldTypes = getFieldTypes(repeatedFields, javaClass)
- val repeatedFieldLists = repeatedFields.zip(repeatedFieldTypes.unzip._1).map(x => "val "+x._1.getName+":List["+x._2+"]")
+ val repeatedFieldDefaults = repeatedFields.zip(repeatedFieldTypes.unzip._1).map(x => x._1.getName+":List["+x._2+"] = Nil")
val repeatedFieldListBuffers = repeatedFields.zip(repeatedFieldTypes.unzip._1).map(x => "val "+x._1.getName+":ListBuffer["+x._2+"] = new ListBuffer["+x._2+"]")
val name = descriptor.getName
val javaSubClass = javaClass+"."+getContainingType(descriptor.getContainingType)+name
out.println
- out.print("class "+name+"(")
- val spaces = " "*(name.length+7)
- out.println((requiredFieldVals++optionalFieldVals++repeatedFieldLists).mkString(",\n"+spaces))
- out.println(" ) extends TypedMessage["+javaSubClass+"] {")
+ out.print("case class "+name+"(")
+ val spaces = " "*(name.length+12)
+ out.println((requiredFieldDecls++optionalFieldDefaults++repeatedFieldDefaults).mkString(",\n"+spaces))
+ out.println(" ) extends TypedMessage["+name+","+javaSubClass+"] {")
out.println(" def javaMessage:"+javaSubClass+" = {")
out.println(" val builder = "+javaSubClass+".newBuilder")
for ((field, isMessage) <- requiredFields.zip(requiredFieldTypes.unzip._2)) {
@@ -124,6 +125,15 @@ object ScalaProtoWrapperGenerator {
out.println(" }")
}
out.println(" }")
+ out.println
+ out.println(" def copyAndSet(i:Int, fieldValue:Any):"+name+" = {")
+ if (!requiredFields.isEmpty || !optionalFields.isEmpty) {
+ out.println(" i match {")
+ requiredFields.foreach(field => out.println(" case "+field.getNumber+" => copy("+field.getName+" = fieldValue.asInstanceOf["+getTypeString(field, javaClass)._1+"])"))
+ optionalFields.foreach(field => out.println(" case "+field.getNumber+" => copy("+field.getName+" = fieldValue.asInstanceOf[Option["+getTypeString(field, javaClass)._1+"]])"))
+ out.println(" }")
+ } else out.println(" this")
+ out.println(" }")
out.println("}")
out.println
@@ -174,7 +184,7 @@ object ScalaProtoWrapperGenerator {
out.println(" "+field)
}
out.println
- out.println(" def set(i:Int, fieldValue:Option[Any]):Unit = {")
+ out.println(" def set(i:Int, fieldValue:Any):Unit = {")
if (!requiredFields.isEmpty || !optionalFields.isEmpty) {
out.println(" i match {")
requiredFields.foreach(field => out.println(" case "+field.getNumber+" => "+field.getName+" = fieldValue.asInstanceOf["+getTypeString(field, javaClass)._1+"]"))

0 comments on commit d60aa2c

Please sign in to comment.
Something went wrong with that request. Please try again.