Skip to content

Commit

Permalink
Merge pull request #91 from xflin/issue85
Browse files Browse the repository at this point in the history
fixed issue#85 when a fullname is used in a proto, ScalaBuff generates incorrect Scala code
  • Loading branch information
SandroGrzicic committed Feb 9, 2015
2 parents 693b313 + 13091b3 commit fa7b062
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -758,11 +758,17 @@ object Generator {
field.fType.scalaType.split("\\.")(0)
else
field.fType.scalaType
importedSymbols.get(scalaType).foreach { symbol =>
// namespaces might be empty for imported message types
val namespacePrefix = if (symbol.packageName.isEmpty) "" else symbol.packageName + "."
field.fType.scalaType = namespacePrefix + field.fType.scalaType
field.fType.defaultValue = namespacePrefix + field.fType.defaultValue
importedSymbols.filter {
case (name, symbol) =>
val shortName = scalaType.stripPrefix(symbol.protoPackage + ".")
name == shortName || shortName.startsWith(name + ".")
}.foreach {
case (name, symbol) =>
// namespaces might be empty for imported message types
val namespacePrefix = if (symbol.packageName.isEmpty) "" else symbol.packageName + "."
val protoPkgPrefix = if (symbol.protoPackage.isEmpty) "" else symbol.protoPackage + "."
field.fType.scalaType = namespacePrefix + field.fType.scalaType.stripPrefix(protoPkgPrefix)
field.fType.defaultValue = namespacePrefix + field.fType.defaultValue.stripPrefix(protoPkgPrefix)
}
}
case _ =>
Expand All @@ -772,7 +778,7 @@ object Generator {
}
}

case class ImportedSymbol(packageName: String, isEnum: Boolean)
case class ImportedSymbol(packageName: String, isEnum: Boolean, protoPackage: String = "")

/**
* A generated Scala class. The path is relative.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,17 @@ object ScalaBuff {
* files and building a map of their exported symbols.
*/
def processImportSymbols(tree: List[Node])(implicit settings: Settings = defaultSettings): Map[String, ImportedSymbol] = {
def dig(name: String) = {
def dig(name: String): List[(String, ImportedSymbol)] = {
val tree = parse(searchPath(name).getOrElse { throw new IOException("Unable to import: " + name) })
val packageName = tree.collectFirst {
case OptionValue(key, value) if key == "java_package" => value.stripQuotes
}.getOrElse("")
val protoPackage = tree.collectFirst {
case PackageStatement(name) => name
}.getOrElse("")
tree.collect {
case Message(name, _) => (name, ImportedSymbol(packageName, false))
case EnumStatement(name, _, _) => (name, ImportedSymbol(packageName, true))
case Message(name, _) => (name, ImportedSymbol(packageName, false, protoPackage))
case EnumStatement(name, _, _) => (name, ImportedSymbol(packageName, true, protoPackage))
}
}
tree.collect {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ final case class UsesImportPackage (
output.writeMessage(1, `packageTest`)
}

lazy val getSerializedSize = {
def getSerializedSize = {
import com.google.protobuf.CodedOutputStream._
var __size = 0
__size += computeMessageSize(1, `packageTest`)
Expand Down Expand Up @@ -79,4 +79,14 @@ object ImportPackages {
def registerAllExtensions(registry: com.google.protobuf.ExtensionRegistryLite) {
}

private val fromBinaryHintMap = collection.immutable.HashMap[String, Array[Byte] com.google.protobuf.GeneratedMessageLite](
"UsesImportPackage" -> (bytes UsesImportPackage.parseFrom(bytes))
)

def deserializePayload(payload: Array[Byte], payloadType: String): com.google.protobuf.GeneratedMessageLite = {
fromBinaryHintMap.get(payloadType) match {
case Some(f) f(payload)
case None throw new IllegalArgumentException(s"unimplemented deserialization of message payload of type [${payloadType}]")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Generated by ScalaBuff, the Scala Protocol Buffers compiler. DO NOT EDIT!
// source: import_use_fullname.proto

package resources.generated

//import "package_name.proto"

final case class UseFullImportedName (
`fullnameTest`: resources.generated.nested.PackageTest = resources.generated.nested.PackageTest.defaultInstance
) extends com.google.protobuf.GeneratedMessageLite
with com.google.protobuf.MessageLite.Builder
with net.sandrogrzicic.scalabuff.Message[UseFullImportedName]
with net.sandrogrzicic.scalabuff.Parser[UseFullImportedName] {



def writeTo(output: com.google.protobuf.CodedOutputStream) {
output.writeMessage(1, `fullnameTest`)
}

def getSerializedSize = {
import com.google.protobuf.CodedOutputStream._
var __size = 0
__size += computeMessageSize(1, `fullnameTest`)

__size
}

def mergeFrom(in: com.google.protobuf.CodedInputStream, extensionRegistry: com.google.protobuf.ExtensionRegistryLite): UseFullImportedName = {
import com.google.protobuf.ExtensionRegistryLite.{getEmptyRegistry => _emptyRegistry}
var __fullnameTest: resources.generated.nested.PackageTest = resources.generated.nested.PackageTest.defaultInstance

def __newMerged = UseFullImportedName(
__fullnameTest
)
while (true) in.readTag match {
case 0 => return __newMerged
case 10 => __fullnameTest = readMessage[resources.generated.nested.PackageTest](in, __fullnameTest, _emptyRegistry)
case default => if (!in.skipField(default)) return __newMerged
}
null
}

def mergeFrom(m: UseFullImportedName) = {
UseFullImportedName(
m.`fullnameTest`
)
}

def getDefaultInstanceForType = UseFullImportedName.defaultInstance
def clear = getDefaultInstanceForType
def isInitialized = true
def build = this
def buildPartial = this
def parsePartialFrom(cis: com.google.protobuf.CodedInputStream, er: com.google.protobuf.ExtensionRegistryLite) = mergeFrom(cis, er)
override def getParserForType = this
def newBuilderForType = getDefaultInstanceForType
def toBuilder = this
def toJson(indent: Int = 0): String = "ScalaBuff JSON generation not enabled. Use --generate_json_method to enable."
}

object UseFullImportedName {
@reflect.BeanProperty val defaultInstance = new UseFullImportedName()

def parseFrom(data: Array[Byte]): UseFullImportedName = defaultInstance.mergeFrom(data)
def parseFrom(data: Array[Byte], offset: Int, length: Int): UseFullImportedName = defaultInstance.mergeFrom(data, offset, length)
def parseFrom(byteString: com.google.protobuf.ByteString): UseFullImportedName = defaultInstance.mergeFrom(byteString)
def parseFrom(stream: java.io.InputStream): UseFullImportedName = defaultInstance.mergeFrom(stream)
def parseDelimitedFrom(stream: java.io.InputStream): Option[UseFullImportedName] = defaultInstance.mergeDelimitedFromStream(stream)

val FULLNAME_TEST_FIELD_NUMBER = 1

def newBuilder = defaultInstance.newBuilderForType
def newBuilder(prototype: UseFullImportedName) = defaultInstance.mergeFrom(prototype)

}

object ImportUseFullname {
def registerAllExtensions(registry: com.google.protobuf.ExtensionRegistryLite) {
}

private val fromBinaryHintMap = collection.immutable.HashMap[String, Array[Byte] com.google.protobuf.GeneratedMessageLite](
"UseFullImportedName" -> (bytes UseFullImportedName.parseFrom(bytes))
)

def deserializePayload(payload: Array[Byte], payloadType: String): com.google.protobuf.GeneratedMessageLite = {
fromBinaryHintMap.get(payloadType) match {
case Some(f) f(payload)
case None throw new IllegalArgumentException(s"unimplemented deserialization of message payload of type [${payloadType}]")
}
}
}
12 changes: 11 additions & 1 deletion scalabuff-compiler/src/test/resources/generated/MultiOne.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final case class MutiMessageOne (
def writeTo(output: com.google.protobuf.CodedOutputStream) {
}

lazy val getSerializedSize = {
def getSerializedSize = {
import com.google.protobuf.CodedOutputStream._
var __size = 0

Expand Down Expand Up @@ -72,4 +72,14 @@ object MultiOne {
def registerAllExtensions(registry: com.google.protobuf.ExtensionRegistryLite) {
}

private val fromBinaryHintMap = collection.immutable.HashMap[String, Array[Byte] com.google.protobuf.GeneratedMessageLite](
"MutiMessageOne" -> (bytes MutiMessageOne.parseFrom(bytes))
)

def deserializePayload(payload: Array[Byte], payloadType: String): com.google.protobuf.GeneratedMessageLite = {
fromBinaryHintMap.get(payloadType) match {
case Some(f) f(payload)
case None throw new IllegalArgumentException(s"unimplemented deserialization of message payload of type [${payloadType}]")
}
}
}
12 changes: 11 additions & 1 deletion scalabuff-compiler/src/test/resources/generated/MultiTwo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ final case class MultiMessageTwo (
if (`stringDefault`.isDefined) output.writeString(6, `stringDefault`.get)
}

lazy val getSerializedSize = {
def getSerializedSize = {
import com.google.protobuf.CodedOutputStream._
var __size = 0
__size += computeInt32Size(1, `requiredField`)
Expand Down Expand Up @@ -130,4 +130,14 @@ object MultiTwo {
def registerAllExtensions(registry: com.google.protobuf.ExtensionRegistryLite) {
}

private val fromBinaryHintMap = collection.immutable.HashMap[String, Array[Byte] com.google.protobuf.GeneratedMessageLite](
"MultiMessageTwo" -> (bytes MultiMessageTwo.parseFrom(bytes))
)

def deserializePayload(payload: Array[Byte], payloadType: String): com.google.protobuf.GeneratedMessageLite = {
fromBinaryHintMap.get(payloadType) match {
case Some(f) f(payload)
case None throw new IllegalArgumentException(s"unimplemented deserialization of message payload of type [${payloadType}]")
}
}
}
33 changes: 31 additions & 2 deletions scalabuff-compiler/src/test/resources/generated/Simple.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ final case class SimpleTest (
if (`floatNegative`.isDefined) output.writeFloat(9, `floatNegative`.get)
}

lazy val getSerializedSize = {
def getSerializedSize = {
import com.google.protobuf.CodedOutputStream._
var __size = 0
__size += computeInt32Size(1, `requiredField`)
Expand Down Expand Up @@ -129,7 +129,26 @@ final case class SimpleTest (
override def getParserForType = this
def newBuilderForType = getDefaultInstanceForType
def toBuilder = this
def toJson(indent: Int = 0): String = "ScalaBuff JSON generation not enabled. Use --generate_json_method to enable."
def toJson(indent: Int = 0): String = {
val indent0 = "\n" + ("\t" * indent)
val (indent1, indent2) = (indent0 + "\t", indent0 + "\t\t")
val sb = StringBuilder.newBuilder
sb
.append("{")
sb.append(indent1).append("\"requiredField\": ").append("\"").append(`requiredField`).append("\"").append(',')
if (`optionalField`.isDefined) { sb.append(indent1).append("\"optionalField\": ").append("\"").append(`optionalField`.get).append("\"").append(',') }
sb.append(indent1).append("\"repeatedField\": [").append(indent2).append(`repeatedField`.map("\"" + _ + "\"").mkString(", " + indent2)).append(indent1).append(']').append(',')
if (`type`.isDefined) { sb.append(indent1).append("\"type\": ").append("\"").append(`type`.get).append("\"").append(',') }
if (`int32Default`.isDefined) { sb.append(indent1).append("\"int32Default\": ").append("\"").append(`int32Default`.get).append("\"").append(',') }
if (`int32Negative`.isDefined) { sb.append(indent1).append("\"int32Negative\": ").append("\"").append(`int32Negative`.get).append("\"").append(',') }
if (`stringDefault`.isDefined) { sb.append(indent1).append("\"stringDefault\": ").append("\"").append(`stringDefault`.get).append("\"").append(',') }
if (`floatDefault`.isDefined) { sb.append(indent1).append("\"floatDefault\": ").append("\"").append(`floatDefault`.get).append("\"").append(',') }
if (`floatNegative`.isDefined) { sb.append(indent1).append("\"floatNegative\": ").append("\"").append(`floatNegative`.get).append("\"").append(',') }
sb.length -= 1
sb.append(indent0).append("}")
sb.toString()
}

}

object SimpleTest {
Expand Down Expand Up @@ -160,4 +179,14 @@ object Simple {
def registerAllExtensions(registry: com.google.protobuf.ExtensionRegistryLite) {
}

private val fromBinaryHintMap = collection.immutable.HashMap[String, Array[Byte] com.google.protobuf.GeneratedMessageLite](
"SimpleTest" -> (bytes SimpleTest.parseFrom(bytes))
)

def deserializePayload(payload: Array[Byte], payloadType: String): com.google.protobuf.GeneratedMessageLite = {
fromBinaryHintMap.get(payloadType) match {
case Some(f) f(payload)
case None throw new IllegalArgumentException(s"unimplemented deserialization of message payload of type [${payloadType}]")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ final case class PackageTest (
output.writeInt32(1, `requiredField`)
}

lazy val getSerializedSize = {
def getSerializedSize = {
import com.google.protobuf.CodedOutputStream._
var __size = 0
__size += computeInt32Size(1, `requiredField`)
Expand Down Expand Up @@ -77,4 +77,14 @@ object PackageName {
def registerAllExtensions(registry: com.google.protobuf.ExtensionRegistryLite) {
}

private val fromBinaryHintMap = collection.immutable.HashMap[String, Array[Byte] com.google.protobuf.GeneratedMessageLite](
"PackageTest" -> (bytes PackageTest.parseFrom(bytes))
)

def deserializePayload(payload: Array[Byte], payloadType: String): com.google.protobuf.GeneratedMessageLite = {
fromBinaryHintMap.get(payloadType) match {
case Some(f) f(payload)
case None throw new IllegalArgumentException(s"unimplemented deserialization of message payload of type [${payloadType}]")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
List(PackageStatement(resources.generated), ImportStatement("package_name.proto"), OptionValue(optimize_for,LITE_RUNTIME), Message(UseFullImportedName,MessageBody(List(Field(required,resources.generated.nested.PackageTest,fullname_test,1,List(),)),List(),List(),List(),List(),List(),List())))
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package resources.generated;

import "package_name.proto";

option optimize_for = LITE_RUNTIME;

message UseFullImportedName {
required resources.generated.nested.PackageTest fullname_test = 1;
}
1 change: 1 addition & 0 deletions scalabuff-compiler/src/test/tests/ScalaBuffTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class ScalaBuffTest extends FunSuite with ShouldMatchers {

compile("package_name", Some("nested"))
compile("import_packages", None)
compile("import_use_fullname", None)
}

test("run: unknown option") {
Expand Down

0 comments on commit fa7b062

Please sign in to comment.