diff --git a/build.sbt b/build.sbt index 171effdd8..51f723e6c 100644 --- a/build.sbt +++ b/build.sbt @@ -306,10 +306,12 @@ lazy val e2e = (project in file("e2e")) .dependsOn(grpcRuntime) .settings(e2eCommonSettings) .settings( + libraryDependencies += "org.typelevel" %% "cats-core" % "2.3.0", scalacOptions ++= Seq( "-P:silencer:globalFilters=eprecatedInt32 in class TestDeprecatedFields is deprecated", "-P:silencer:pathFilters=custom_options_use;CustomAnnotationProto.scala;changed/scoped;ServerReflectionGrpc.scala", - "-P:silencer:lineContentFilters=import com.thesamet.pb.MisplacedMapper.weatherMapper" + "-P:silencer:lineContentFilters=import com.thesamet.pb.MisplacedMapper.weatherMapper", + "-P:silencer:lineContentFilters=import Ordering" ), Compile / PB.protoSources += (Compile / PB.externalIncludePath).value / "grpc" / "reflection", Compile / PB.generate := ((Compile / PB.generate) dependsOn (protocGenScalaUnix / Compile / assembly)).value, diff --git a/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorImplicits.scala b/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorImplicits.scala index f4516fdf8..2cbd6bc29 100644 --- a/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorImplicits.scala +++ b/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorImplicits.scala @@ -254,14 +254,14 @@ class DescriptorImplicits(params: GeneratorParams, files: Seq[FileDescriptor]) { if (isSingular) EnclosingType.None else if (supportsPresence || fd.isInOneof) EnclosingType.ScalaOption else { - EnclosingType.Collection(collectionType) + EnclosingType.Collection(collectionType, collection.adapter) } def fieldMapEnclosingType: EnclosingType = if (isSingular) EnclosingType.None else if (supportsPresence || fd.isInOneof) EnclosingType.ScalaOption - else if (!fd.isMapField) EnclosingType.Collection(collectionType) - else EnclosingType.Collection(ScalaSeq) + else if (!fd.isMapField) EnclosingType.Collection(collectionType, collection.adapter) + else EnclosingType.Collection(ScalaSeq, None) def isMapField = isMessage && fd.isRepeated && fd.getMessageType.isMapEntry @@ -270,30 +270,73 @@ class DescriptorImplicits(params: GeneratorParams, files: Seq[FileDescriptor]) { fd.getMessageType.mapType } - def collectionBuilder: String = { - require(fd.isRepeated) - val t = if (collectionType == ScalaSeq) ScalaVector else collectionType + class CollectionHelpers { + def newBuilder: String = { + val t = if (collectionType == ScalaSeq) ScalaVector else collectionType - if (!fd.isMapField) - s"$t.newBuilder[$singleScalaTypeName]" - else { - s"$t.newBuilder[${fd.mapType.keyType}, ${fd.mapType.valueType}]" + if (!fd.isMapField) { + adapter match { + case None => s"$t.newBuilder[$singleScalaTypeName]" + case Some(tc) => s"$tc.newBuilder[$singleScalaTypeName]" + } + } else { + adapter match { + case None => s"$t.newBuilder[${fd.mapType.keyType}, ${fd.mapType.valueType}]" + case Some(tc) => s"$tc.newBuilder[${fd.mapType.keyType}, ${fd.mapType.valueType}]" + } + } + } + + def empty: String = adapter match { + case None => s"${collectionType}.empty" + case Some(tc) => s"$tc.empty" + } + + def foreach = adapter match { + case None => fd.scalaName.asSymbol + ".foreach" + case Some(tc) => s"$tc.foreach(${fd.scalaName.asSymbol})" + } + + def concat(left: String, right: String) = adapter match { + case None => s"$left ++ $right" + case Some(tc) => s"$tc.concat($left, $right)" } - } - def emptyCollection: String = { - s"${collectionType}.empty" + def nonEmptyType = fd.fieldOptions.getCollection.getNonEmpty + + def nonEmptyCheck(expr: String) = if (nonEmptyType) "true" else s"$expr.nonEmpty" + + def adapter: Option[String] = { + if (fd.fieldOptions.getCollection.hasAdapter()) + Some(fd.fieldOptions.getCollection.getAdapter()) + else None + } + + + def size: Expression = adapter match { + case None => MethodApplication("size") + case Some(tc) => FunctionApplication(s"$tc.size") + } + + def iterator(e: String): String = adapter match { + case None => s"$e.iterator" + case Some(tc) => s"$tc.toIterator($e)" + } } + def collection: CollectionHelpers = new CollectionHelpers + // In scalapb.proto, we separate between collection_type and map_type, but internally this is unified. def collectionType: String = { require(fd.isRepeated) if (fd.isMapField) { - if (fd.fieldOptions.hasMapType) fd.fieldOptions.getMapType + if (fd.fieldOptions.getCollection.hasType) fd.fieldOptions.getCollection.getType + else if (fd.fieldOptions.hasMapType) fd.fieldOptions.getMapType else if (fd.getFile.scalaOptions.hasMapType) fd.getFile.scalaOptions.getMapType else ScalaMap } else { - if (fd.fieldOptions.hasCollectionType) fd.fieldOptions.getCollectionType + if (fd.fieldOptions.getCollection.hasType) fd.fieldOptions.getCollection.getType + else if (fd.fieldOptions.hasCollectionType) fd.fieldOptions.getCollectionType else if (fd.getFile.scalaOptions.hasCollectionType) fd.getFile.scalaOptions.getCollectionType else ScalaSeq @@ -302,15 +345,15 @@ class DescriptorImplicits(params: GeneratorParams, files: Seq[FileDescriptor]) { def fieldMapCollection(innerType: String) = { if (supportsPresence) s"_root_.scala.Option[$innerType]" - else if (fd.isRepeated && !fd.isMapField) s"${collectionType}[$innerType]" else if (fd.isRepeated && fd.isMapField) s"${ScalaSeq}[$innerType]" + else if (fd.isRepeated && !fd.isMapField) s"${collectionType}[$innerType]" else innerType } def fieldsMapEmptyCollection: String = { require(fd.isRepeated) if (fd.isMapField) s"$ScalaSeq.empty" - else emptyCollection + else collection.empty } def scalaTypeName: String = diff --git a/compiler-plugin/src/main/scala/scalapb/compiler/ExpressionBuilder.scala b/compiler-plugin/src/main/scala/scalapb/compiler/ExpressionBuilder.scala index f70676394..aed35035c 100644 --- a/compiler-plugin/src/main/scala/scalapb/compiler/ExpressionBuilder.scala +++ b/compiler-plugin/src/main/scala/scalapb/compiler/ExpressionBuilder.scala @@ -11,8 +11,22 @@ sealed trait Expression extends Product with Serializable { case (e1: LiteralExpression, e2: LiteralExpression) => ExpressionList(e2 :: e1 :: Nil) } - def apply(e: String, enclosingType: EnclosingType, mustCopy: Boolean = false): String = - ExpressionBuilder.run(this)(e, enclosingType, mustCopy) + def apply( + e: String, + sourceType: EnclosingType, + targetType: EnclosingType, + mustCopy: Boolean + ): String = + ExpressionBuilder.run(this, e, sourceType, targetType, mustCopy) + + def apply(e: String, sourceType: EnclosingType, targetType: EnclosingType): String = + ExpressionBuilder.run(this, e, sourceType, targetType, false) + + def apply(e: String, sourceType: EnclosingType, mustCopy: Boolean): String = + ExpressionBuilder.run(this, e, sourceType, sourceType, mustCopy) + + def apply(e: String, sourceType: EnclosingType): String = + ExpressionBuilder.run(this, e, sourceType, sourceType, false) } case class ExpressionList(l: List[LiteralExpression]) extends Expression @@ -51,23 +65,24 @@ object ExpressionBuilder { case OperatorApplication(name) :: tail => s"${runSingleton(tail)(e)} $name" } - def convertCollection(expr: String, enclosingType: EnclosingType): String = { - val convert = List(enclosingType match { - case Collection(DescriptorImplicits.ScalaVector) => MethodApplication("toVector") - case Collection(DescriptorImplicits.ScalaSeq) => MethodApplication("toSeq") - case Collection(DescriptorImplicits.ScalaMap) => MethodApplication("toMap") - case Collection(DescriptorImplicits.ScalaIterable) => + def convertCollection(expr: String, targetType: EnclosingType): String = { + val convert = List(targetType match { + case Collection(_, Some(tc)) => FunctionApplication(s"${tc}.fromIterator") + case Collection(DescriptorImplicits.ScalaVector, _) => MethodApplication("toVector") + case Collection(DescriptorImplicits.ScalaSeq, _) => MethodApplication("toSeq") + case Collection(DescriptorImplicits.ScalaMap, _) => MethodApplication("toMap") + case Collection(DescriptorImplicits.ScalaIterable, _) => FunctionApplication("_root_.scalapb.internal.compat.toIterable") - case Collection(_) => FunctionApplication("_root_.scalapb.internal.compat.convertTo") - case _ => Identity + case Collection(_, _) => FunctionApplication("_root_.scalapb.internal.compat.convertTo") + case _ => Identity }) runSingleton(convert)(expr) } def runCollection( es: List[LiteralExpression] - )(e0: String, enclosingType: EnclosingType, mustCopy: Boolean): String = { - require(enclosingType != EnclosingType.None) + )(e0: String, sourceType: EnclosingType, targetType: EnclosingType, mustCopy: Boolean): String = { + require(sourceType != EnclosingType.None) val nontrivial: List[LiteralExpression] = es.filterNot(_.isIdentity) val needVariable = nontrivial @@ -75,12 +90,19 @@ object ExpressionBuilder { .dropRight(1) .exists(_.isFunctionApplication) - val e = if (enclosingType.isInstanceOf[Collection]) { - e0 + ".iterator" - } else e0 + val e = sourceType match { + case Collection(_, Some(tc)) => s"$tc.toIterator($e0)" + case Collection(_, None) => s"$e0.iterator" + case _ => e0 + } + + val forceTypeConversion = sourceType match { + case Collection(_, Some(_)) if sourceType != targetType => true + case _ => false + } if (needVariable) - convertCollection(s"""$e.map(__e => ${runSingleton(nontrivial)("__e")})""", enclosingType) + convertCollection(s"""$e.map(__e => ${runSingleton(nontrivial)("__e")})""", targetType) else if (nontrivial.nonEmpty) { val f = nontrivial match { case List(FunctionApplication(name)) => @@ -88,27 +110,35 @@ object ExpressionBuilder { case _ => runSingleton(nontrivial)("_") } - convertCollection(s"""$e.map($f)""", enclosingType) + convertCollection(s"""$e.map($f)""", targetType) } else if (mustCopy) { - convertCollection(s"""$e.map(_root_.scala.Predef.identity)""", enclosingType) + convertCollection(s"""$e.map(_root_.scala.Predef.identity)""", targetType) + } else if (forceTypeConversion) { + convertCollection(e, targetType) } else e0 } - def run( - es: List[LiteralExpression] - )(e: String, enclosingType: EnclosingType, mustCopy: Boolean): String = - enclosingType match { + private[scalapb] def run( + es: List[LiteralExpression], e: String, sourceType: EnclosingType, targetType: EnclosingType, mustCopy: Boolean): String = + sourceType match { case EnclosingType.None => runSingleton(es)(e) case _ => - runCollection(es)(e, enclosingType, mustCopy) + runCollection(es)(e, sourceType, targetType, mustCopy) } - def run(es: Expression)(e: String, enclosingType: EnclosingType, mustCopy: Boolean): String = + private[scalapb] def run( + es: Expression, e: String, sourceType: EnclosingType, targetType: EnclosingType, mustCopy: Boolean): String = es match { - case ExpressionList(l) => run(l)(e, enclosingType, mustCopy) - case expr: LiteralExpression => run(expr :: Nil)(e, enclosingType, mustCopy) + case ExpressionList(l) => run(l, e, sourceType, targetType, mustCopy) + case expr: LiteralExpression => run(expr :: Nil, e, sourceType, targetType, mustCopy) } + + @deprecated("0.10.10", "Use Expression.run") + def run( + es: Expression + )(e: String, sourceType: EnclosingType, mustCopy: Boolean): String = + run(es, e, sourceType, sourceType, mustCopy) } sealed trait EnclosingType @@ -119,5 +149,7 @@ object EnclosingType { /** Indicates that the result should be a collection with type constructor cc, such as List, Map. */ - case class Collection(cc: String) extends EnclosingType + case class Collection(cc: String, typeClass: Option[String]) extends EnclosingType { + def this(cc: String) { this(cc, scala.None) } + } } diff --git a/compiler-plugin/src/main/scala/scalapb/compiler/ProtobufGenerator.scala b/compiler-plugin/src/main/scala/scalapb/compiler/ProtobufGenerator.scala index 3906a4a87..e928db381 100644 --- a/compiler-plugin/src/main/scala/scalapb/compiler/ProtobufGenerator.scala +++ b/compiler-plugin/src/main/scala/scalapb/compiler/ProtobufGenerator.scala @@ -184,7 +184,7 @@ class ProtobufGenerator( def defaultValueForDefaultInstance(field: FieldDescriptor) = if (field.supportsPresence) C.None - else if (field.isRepeated) field.emptyCollection + else if (field.isRepeated) field.collection.empty else defaultValueForGet(field) def javaToScalaConversion(field: FieldDescriptor) = { @@ -212,11 +212,12 @@ class ProtobufGenerator( val valueConversion: Expression = javaToScalaConversion(field) if (field.supportsPresence) - s"if ($javaHazzer) Some(${valueConversion.apply(javaGetter, enclosingType = EnclosingType.None)}) else ${C.None}" + s"if ($javaHazzer) Some(${valueConversion.apply(javaGetter, EnclosingType.None)}) else ${C.None}" else if (field.isRepeated) valueConversion( javaGetter + ".asScala", - EnclosingType.Collection(field.collectionType), + sourceType = EnclosingType.Collection(DescriptorImplicits.ScalaSeq, None), + targetType = field.enclosingType, mustCopy = true ) else valueConversion(javaGetter, EnclosingType.None) @@ -289,7 +290,7 @@ class ProtobufGenerator( else "") s"""$javaObject - | .$putAll($scalaObject.${fieldAccessorSymbol(field)}.iterator.map { + | .$putAll(${field.collection.iterator(scalaObject + "." + field.scalaName.asSymbol)}.map { | __kv => (${valueConvert("__kv._1", field.mapType.keyField)}, ${valueConvert( "__kv._2", field.mapType.valueField @@ -315,9 +316,10 @@ class ProtobufGenerator( (toBaseTypeExpr(field) andThen scalaToJava(field, boxPrimitives = field.isRepeated)) .apply( scalaGetter, - enclosingType = field.enclosingType match { - case EnclosingType.Collection(_) => - EnclosingType.Collection(DescriptorImplicits.ScalaIterable) + sourceType = field.enclosingType, + targetType = field.enclosingType match { + case _: EnclosingType.Collection => + EnclosingType.Collection(DescriptorImplicits.ScalaIterable, None) case o => o } ) @@ -339,7 +341,11 @@ class ProtobufGenerator( .print(message.fields) { case (fp, f) => val e = toBaseFieldType(f) - .apply(fieldAccessorSymbol(f), enclosingType = f.fieldMapEnclosingType) + .apply( + fieldAccessorSymbol(f), + sourceType = f.enclosingType, + targetType = f.fieldMapEnclosingType + ) if (f.supportsPresence || f.isInOneof) fp.add(s"case ${f.getNumber} => $e.orNull") else if (f.isOptional) { @@ -396,9 +402,10 @@ class ProtobufGenerator( .andThen(singleFieldAsPvalue(f)) .apply( fieldAccessorSymbol(f), - enclosingType = f.enclosingType match { - case EnclosingType.Collection(_) => - EnclosingType.Collection(DescriptorImplicits.ScalaVector) + sourceType = f.enclosingType, + targetType = f.enclosingType match { + case _: EnclosingType.Collection => + EnclosingType.Collection(DescriptorImplicits.ScalaVector, None) case other => other } ) @@ -507,16 +514,16 @@ class ProtobufGenerator( val tagSize = CodedOutputStream.computeTagSize(field.getNumber) if (!field.isPacked) { Types.fixedSize(field.getType) match { - case Some(size) => fp.add(s"__size += ${size + tagSize} * $fieldNameSymbol.size") + case Some(size) => fp.add(s"__size += ${size + tagSize} * ${field.collection.size(field.scalaName.asSymbol, EnclosingType.None)}") case None => - fp.add(s"""$fieldNameSymbol.foreach { __item => + fp.add(s"""${field.collection.foreach} { __item => | val __value = ${toBaseType(field)("__item")} | __size += ${sizeExpressionForSingleField(field, "__value")} |}""".stripMargin) } } else { val fieldName = field.scalaName - fp.add(s"""if($fieldNameSymbol.nonEmpty) { + fp.add(s"""if (${field.collection.nonEmptyCheck(fieldNameSymbol)}) { | val __localsize = ${fieldName}SerializedSize | __size += $tagSize + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize |}""".stripMargin) @@ -569,7 +576,7 @@ class ProtobufGenerator( .call({ fp => Types.fixedSize(field.getType) match { case Some(size) => - fp.add(s" $size * ${field.scalaName.asSymbol}.size").add("}") + fp.add(s" $size * ${field.collection.size(field.scalaName.asSymbol, EnclosingType.None)}").add("}") case None => val capTypeName = Types.capitalizedType(field.getType) val sizeFunc = FunctionApplication( @@ -585,7 +592,7 @@ class ProtobufGenerator( fp.indent .add(s"if (__${methodName}Field == 0) __${methodName}Field = {") .add(s" var __s: _root_.scala.Int = 0") - .add(s" ${field.scalaName.asSymbol}.foreach(__i => __s += $sizeExpr)") + .add(s" ${field.collection.foreach}(__i => __s += $sizeExpr)") .add(s" __s") .add(s"}") .add(s"__${methodName}Field") @@ -626,10 +633,10 @@ class ProtobufGenerator( ) ) - printer.add(s"""if (${fieldNameSymbol}.nonEmpty) { + printer.add(s"""if (${field.collection.nonEmptyCheck(fieldNameSymbol)}) { | _output__.writeTag(${field.getNumber}, 2) | _output__.writeUInt32NoTag(${field.scalaName}SerializedSize) - | ${fieldNameSymbol}.foreach($writeFunc) + | ${field.collection.foreach}($writeFunc) |};""".stripMargin) } else if (field.isRequired) { printer @@ -656,7 +663,8 @@ class ProtobufGenerator( .add("};") } else { printer - .add(s"${fieldNameSymbol}.foreach { __v =>") + .when(field.isRepeated)(_.add(s"${field.collection.foreach} { __v =>")) + .when(!field.isRepeated)(_.add(s"${fieldAccessorSymbol(field)}.foreach { __v =>")) .indent .add(s"val __m = ${toBaseType(field)("__v")}") .call(generateWriteSingleValue(field, "__m")) @@ -679,7 +687,8 @@ class ProtobufGenerator( if (message.getFile.noDefaultValuesInConstructor) None else if (field.isOptional && field.supportsPresence) Some(C.None) else if (field.isSingular && !field.isRequired) Some(defaultValueForGet(field).toString) - else if (field.isRepeated) Some(s"${field.emptyCollection}") + else if (field.isRepeated && !field.collection.nonEmptyType) + Some(s"${field.collection.empty}") else None ConstructorField( @@ -730,13 +739,18 @@ class ProtobufGenerator( defaultValueForDefaultInstance(field), s"_message__.${field.scalaName.asSymbol}" ) - else + else { + val it = + if (field.collection.adapter.isDefined) + field.collection.iterator(s"_message__.${field.scalaName.asSymbol}") + else s"_message__.${field.scalaName.asSymbol}" Field( s"__${field.scalaName}", s"collection.mutable.Builder[${field.singleScalaTypeName}, ${field.scalaTypeName}]", - field.collectionBuilder, - s"${field.collectionBuilder} ++= _message__.${field.scalaName.asSymbol}" + field.collection.newBuilder, + s"${field.collection.newBuilder} ++= $it" ) + } } ++ message.getOneofs.asScala.map { oneof => Field( s"__${oneof.scalaName.name}", @@ -1022,9 +1036,13 @@ class ProtobufGenerator( val e = if (field.supportsPresence) s"$value.flatMap(_.as[$baseTypeName])" - else if (field.isRepeated) - s"$value.map(_.as[${baseTypeName}]).getOrElse(${field.fieldsMapEmptyCollection})" - else if (field.isRequired) + else if (field.isRepeated) { + val reads = field.collection.adapter match { + case Some(tc) if !field.isMapField => s"(${tc}.reads)" + case _ => "" + } + s"$value.map(_.as[${baseTypeName}]$reads).getOrElse(${field.fieldsMapEmptyCollection})" + } else if (field.isRequired) s"$value.get.as[$baseTypeName]" else { // This is for proto3, no default value. @@ -1036,7 +1054,8 @@ class ProtobufGenerator( s"${field.scalaName.asSymbol} = " + transform(field).apply( e, - enclosingType = field.enclosingType + sourceType = field.fieldMapEnclosingType, + targetType = field.enclosingType ) } val oneOfs = message.getOneofs.asScala.map { oneOf => @@ -1157,9 +1176,8 @@ class ProtobufGenerator( .print(customizedFields) { case (printer, (field, customType)) => val modifier = - if (field.getContainingType.isMapEntry) - s"private[${field.getContainingType.getContainingType.scalaType.nameSymbol}]" - else s"private" + if (field.getFile().scalaPackage.fullName.isEmpty) "private" + else s"private[${field.getFile().scalaPackage.fullName.split('.').last}]" printer .add("@transient") .add( @@ -1406,6 +1424,9 @@ class ProtobufGenerator( .add(s"""object $className extends $companionType { | implicit def messageCompanion: $companionType = this""".stripMargin) .indent + .add( + s"override def parseFrom(input: _root_.com.google.protobuf.CodedInputStream): ${message.scalaType.fullName} = newBuilder.merge(input).result()" + ) .when(message.javaConversions)(generateToJavaProto(message)) .when(message.javaConversions)(generateFromJavaProto(message)) .call(generateMerge(message)) @@ -1509,12 +1530,16 @@ class ProtobufGenerator( ) } .when(field.isRepeated) { p => - val emptyValue = field.emptyCollection - p.add( - s"""def $clearMethod = copy(${field.scalaName.asSymbol} = $emptyValue) - |def add${field.upperScalaName}(__vs: $singleType*): ${message.scalaType.nameSymbol} = addAll${field.upperScalaName}(__vs) - |def addAll${field.upperScalaName}(__vs: Iterable[$singleType]): ${message.scalaType.nameSymbol} = copy(${field.scalaName.asSymbol} = ${field.scalaName.asSymbol} ++ __vs)""".stripMargin - ) + val concat = field.collection.concat(field.scalaName.asSymbol, "__vs") + p.when(!field.collection.nonEmptyType)( + _.add( + s"def $clearMethod = copy(${field.scalaName.asSymbol} = ${field.collection.empty})" + ) + ) + .add( + s"""|def add${field.upperScalaName}(__vs: $singleType*): ${message.scalaType.nameSymbol} = addAll${field.upperScalaName}(__vs) + |def addAll${field.upperScalaName}(__vs: Iterable[$singleType]): ${message.scalaType.nameSymbol} = copy(${field.scalaName.asSymbol} = $concat)""".stripMargin + ) } .when(field.isRepeated || field.isSingular) { _.add( diff --git a/docs/src/main/scala/scalapb/perf/protos/EnumVector.scala b/docs/src/main/scala/scalapb/perf/protos/EnumVector.scala index 7751ced8d..9e3417376 100644 --- a/docs/src/main/scala/scalapb/perf/protos/EnumVector.scala +++ b/docs/src/main/scala/scalapb/perf/protos/EnumVector.scala @@ -23,7 +23,7 @@ final case class EnumVector( private[this] var __serializedSizeCachedValue: _root_.scala.Int = 0 private[this] def __computeSerializedValue(): _root_.scala.Int = { var __size = 0 - if(colors.nonEmpty) { + if (colors.nonEmpty) { val __localsize = colorsSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } diff --git a/docs/src/main/scala/scalapb/perf/protos/IntVector.scala b/docs/src/main/scala/scalapb/perf/protos/IntVector.scala index 2f487b80d..9a104b3e2 100644 --- a/docs/src/main/scala/scalapb/perf/protos/IntVector.scala +++ b/docs/src/main/scala/scalapb/perf/protos/IntVector.scala @@ -23,7 +23,7 @@ final case class IntVector( private[this] var __serializedSizeCachedValue: _root_.scala.Int = 0 private[this] def __computeSerializedValue(): _root_.scala.Int = { var __size = 0 - if(ints.nonEmpty) { + if (ints.nonEmpty) { val __localsize = intsSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } diff --git a/e2e/src/main/protobuf/cats_types.proto b/e2e/src/main/protobuf/cats_types.proto new file mode 100644 index 000000000..baca2503f --- /dev/null +++ b/e2e/src/main/protobuf/cats_types.proto @@ -0,0 +1,72 @@ +syntax = "proto2"; + +package com.thesamet.proto.e2e; + +import "scalapb/scalapb.proto"; +import "custom_types.proto"; +import "collection_types.proto"; + +message CollectionTypesNEL { + repeated int32 repeated_int32 = 31 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated int64 repeated_int64 = 32 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated uint32 repeated_uint32 = 33 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated uint64 repeated_uint64 = 34 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sint32 repeated_sint32 = 35 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sint64 repeated_sint64 = 36 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated fixed32 repeated_fixed32 = 37 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated fixed64 repeated_fixed64 = 38 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sfixed32 repeated_sfixed32 = 39 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sfixed64 repeated_sfixed64 = 40 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated float repeated_float = 41 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated double repeated_double = 42 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated bool repeated_bool = 43 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated string repeated_string = 44 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated bytes repeated_bytes = 45 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated Enum repeated_enum = 46 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated SubMsg repeated_msg = 47 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated CustomMessage.Name repeated_fullname = 48 [(scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }, (scalapb.field).type = "com.thesamet.pb.FullName"]; +} + +message CollectionTypesNELPacked { + repeated int32 repeated_int32 = 31 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated int64 repeated_int64 = 32 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated uint32 repeated_uint32 = 33 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated uint64 repeated_uint64 = 34 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sint32 repeated_sint32 = 35 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sint64 repeated_sint64 = 36 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated fixed32 repeated_fixed32 = 37 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated fixed64 repeated_fixed64 = 38 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sfixed32 repeated_sfixed32 = 39 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated sfixed64 repeated_sfixed64 = 40 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated float repeated_float = 41 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated double repeated_double = 42 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated bool repeated_bool = 43 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; + repeated Enum repeated_enum = 46 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptyList", adapter: "com.thesamet.pb.NonEmptyListCollection", non_empty: true }]; +} + +message CollectionTypesNES { + repeated int32 repeated_int32 = 31 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated int64 repeated_int64 = 32 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated uint32 repeated_uint32 = 33 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated uint64 repeated_uint64 = 34 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated sint32 repeated_sint32 = 35 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated sint64 repeated_sint64 = 36 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated fixed32 repeated_fixed32 = 37 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated fixed64 repeated_fixed64 = 38 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated sfixed32 repeated_sfixed32 = 39 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated sfixed64 repeated_sfixed64 = 40 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated float repeated_float = 41 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated double repeated_double = 42 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated bool repeated_bool = 43 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; + repeated Enum repeated_enum = 46 [packed=true, (scalapb.field).collection = {type:"cats.data.NonEmptySet", adapter: "com.thesamet.pb.NonEmptySetCollection", non_empty: true }]; +} + +message CollectionTypesNEM { + map map_int32_bool = 1 [(scalapb.field).collection = {type:"cats.data.NonEmptyMap", adapter: "com.thesamet.pb.NonEmptyMapCollection", non_empty: true }]; + map map_int32_enum = 2 [(scalapb.field).collection = {type:"cats.data.NonEmptyMap", adapter: "com.thesamet.pb.NonEmptyMapCollection", non_empty: true }]; + map map_int32_submsg = 3 [(scalapb.field).collection = {type:"cats.data.NonEmptyMap", adapter: "com.thesamet.pb.NonEmptyMapCollection", non_empty: true }]; + map mymap_int32_bool = 4 [(scalapb.field).collection = {type:"cats.data.NonEmptyMap", adapter: "com.thesamet.pb.NonEmptyMapCollection", non_empty: true }]; + map mymap_int32_enum = 5 [(scalapb.field).collection = {type:"cats.data.NonEmptyMap", adapter: "com.thesamet.pb.NonEmptyMapCollection", non_empty: true }]; + map mymap_int32_submsg = 6 [(scalapb.field).collection = {type:"cats.data.NonEmptyMap", adapter: "com.thesamet.pb.NonEmptyMapCollection", non_empty: true }]; + map repeated_fullname = 7 [(scalapb.field).collection = {type:"cats.data.NonEmptyMap", adapter: "com.thesamet.pb.NonEmptyMapCollection", non_empty: true}, (scalapb.field).value_type="com.thesamet.pb.FullName"]; +} \ No newline at end of file diff --git a/e2e/src/main/protobuf/collection_types.proto b/e2e/src/main/protobuf/collection_types.proto index 735b5b0d5..7f6b940b2 100644 --- a/e2e/src/main/protobuf/collection_types.proto +++ b/e2e/src/main/protobuf/collection_types.proto @@ -152,7 +152,6 @@ message CollectionTypesMap { map mymap_int32_submsg = 6 [(scalapb.field).map_type="com.thesamet.pb.MyMap"]; map repeated_fullname = 7 [(scalapb.field).map_type="com.thesamet.pb.MyMap", (scalapb.field).value_type="com.thesamet.pb.FullName"]; } - message CustomCollection { repeated int32 repeated_int32 = 31 [(scalapb.field).collection_type="com.thesamet.pb.MyVector"]; repeated CustomMessage.Name repeated_fullname = 32 [(scalapb.field).type="com.thesamet.pb.FullName", (scalapb.field).collection_type="com.thesamet.pb.MyVector"]; diff --git a/e2e/src/main/scala-2.12/com/thesamet/pb/cats_types/package.scala b/e2e/src/main/scala-2.12/com/thesamet/pb/cats_types/package.scala new file mode 100644 index 000000000..ad5d5c1b1 --- /dev/null +++ b/e2e/src/main/scala-2.12/com/thesamet/pb/cats_types/package.scala @@ -0,0 +1,15 @@ +package com.thesamet.proto.e2e + +import scalapb.descriptors.EnumValueDescriptor + +package object cats_types { + implicit val enumOrdering: Ordering[com.thesamet.proto.e2e.collection_types.Enum] = + Ordering.fromLessThan((x, y) => x.value < y.value) + + implicit val enumValueDescriptorOrdering: Ordering[EnumValueDescriptor] = + Ordering.fromLessThan((x, y) => x.number < y.number) + + implicit val cgbEnumValueDescriptorOrdering + : Ordering[com.google.protobuf.Descriptors.EnumValueDescriptor] = + Ordering.fromLessThan((x, y) => x.getNumber < y.getNumber()) +} diff --git a/e2e/src/main/scala-2.13/com/thesamet/proto/e2e/cats_types/package.scala b/e2e/src/main/scala-2.13/com/thesamet/proto/e2e/cats_types/package.scala new file mode 100644 index 000000000..892d9aa31 --- /dev/null +++ b/e2e/src/main/scala-2.13/com/thesamet/proto/e2e/cats_types/package.scala @@ -0,0 +1,18 @@ +package com.thesamet.proto.e2e + +import scalapb.descriptors.EnumValueDescriptor + +package object cats_types { + implicit val floatOrdering = Ordering.Float.TotalOrdering + implicit val doubleOrdering = Ordering.Double.TotalOrdering + + implicit val enumOrdering: Ordering[com.thesamet.proto.e2e.collection_types.Enum] = + Ordering.fromLessThan((x, y) => x.value < y.value) + + implicit val enumValueDescriptorOrdering: Ordering[EnumValueDescriptor] = + Ordering.fromLessThan((x, y) => x.number < y.number) + + implicit val cgbEnumValueDescriptorOrdering + : Ordering[com.google.protobuf.Descriptors.EnumValueDescriptor] = + Ordering.fromLessThan((x, y) => x.getNumber < y.getNumber()) +} diff --git a/e2e/src/main/scala/com/thesamet/pb/CatAdapters.scala b/e2e/src/main/scala/com/thesamet/pb/CatAdapters.scala new file mode 100644 index 000000000..4c54d6374 --- /dev/null +++ b/e2e/src/main/scala/com/thesamet/pb/CatAdapters.scala @@ -0,0 +1,71 @@ +package com.thesamet.pb + +import cats.data.{NonEmptyList, NonEmptySet, NonEmptyMap} +import scalapb.descriptors.{Reads, PRepeated, ReadsException} +import scala.collection.immutable.SortedSet +import scala.collection.immutable.SortedMap +import scala.collection.mutable.Builder + +object NonEmptyListCollection { + def foreach[T](coll: NonEmptyList[T])(f: T => Unit) = coll.map(f) + + def empty[T]: NonEmptyList[T] = throw new RuntimeException("No empty instance available for cats.Data.NonEmptyList") + + def reads[T](implicit reads: Reads[T]): Reads[NonEmptyList[T]] = Reads[NonEmptyList[T]] { + case PRepeated(value) => fromIterator(value.map(reads.read).iterator) + case _ => throw new ReadsException("Expected PRepeated") + } + + def newBuilder[T]: Builder[T, NonEmptyList[T]] = List.newBuilder[T].mapResult( + list => NonEmptyList.fromList(list).getOrElse(throw new RuntimeException("Could not build an empty NonEmptyList")) + ) + + def concat[T](first: NonEmptyList[T], second: Iterable[T]) = first ++ second.toList + + def fromIterator[T](x: Iterator[T]): NonEmptyList[T] = (newBuilder[T] ++= x).result() + + def toIterator[T](value: NonEmptyList[T]): Iterator[T] = value.iterator + + def size[T](value: NonEmptyList[T]): Int = value.size +} + +object NonEmptySetCollection { + def foreach[T](coll: NonEmptySet[T])(f: T => Unit) = coll.map(f) + + def empty[T]: NonEmptySet[T] = throw new RuntimeException("No empty instance available for cats.Data.NonEmptySet") + + def reads[T: Ordering](implicit reads: Reads[T]): Reads[NonEmptySet[T]] = Reads[NonEmptySet[T]] { + case PRepeated(value) => fromIterator(value.map(reads.read).iterator) + case _ => throw new ReadsException("Expected PRepeated") + } + + def newBuilder[T : Ordering]: Builder[T, NonEmptySet[T]] = SortedSet.newBuilder[T].mapResult( + set => NonEmptySet.fromSet(set).getOrElse(throw new RuntimeException("Could not build an empty NonEmptySet") + )) + + def concat[T](first: NonEmptySet[T], second: Iterable[T]) = NonEmptySet.fromSetUnsafe(first.toSortedSet ++ second.toSet) + + def fromIterator[T: Ordering](x: Iterator[T]): NonEmptySet[T] = (newBuilder[T] ++= x).result() + + def toIterator[T](value: NonEmptySet[T]): Iterator[T] = value.toSortedSet.iterator + + def size[T](value: NonEmptySet[T]): Int = value.length +} + +object NonEmptyMapCollection { + def foreach[K, V](coll: NonEmptyMap[K, V])(f: ((K, V)) => Unit) = coll.toSortedMap.foreach(f) + + def empty[K, V]: NonEmptyMap[K, V] = throw new RuntimeException("No empty instance available for cats.Data.NonEmptyMap") + + def newBuilder[K : Ordering, V]: Builder[(K, V), NonEmptyMap[K, V]] = SortedMap.newBuilder[K, V].mapResult( + map => NonEmptyMap.fromMap(map).getOrElse(throw new RuntimeException("Could not build an empty NonEmptyMap")) + ) + + def concat[K, V](first: NonEmptyMap[K, V], second: Iterable[(K, V)]) = NonEmptyMap.fromMapUnsafe(first.toSortedMap ++ second.toMap) + + def fromIterator[K: Ordering, V](x: Iterator[(K, V)]): NonEmptyMap[K, V] = (newBuilder[K, V] ++= x).result() + + def toIterator[K, V](value: NonEmptyMap[K, V]): Iterator[(K, V)] = value.toSortedMap.iterator + + def size[K, V](value: NonEmptyMap[K, V]): Int = value.length +} \ No newline at end of file diff --git a/e2e/src/test/scala/CatsTypesSpec.scala b/e2e/src/test/scala/CatsTypesSpec.scala new file mode 100644 index 000000000..9122cf69a --- /dev/null +++ b/e2e/src/test/scala/CatsTypesSpec.scala @@ -0,0 +1,43 @@ +import com.thesamet.proto.e2e.cats_types._ + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.must.Matchers +import cats.data.NonEmptyList +import com.thesamet.pb.FullName +import com.thesamet.proto.e2e.collection_types.{Enum, SubMsg} + +class CatsTypesSpec extends AnyFlatSpec with Matchers { + "Non-empty types" should "throw exception in defaultInstance" in { + intercept[RuntimeException](CollectionTypesNEL.defaultInstance) + intercept[RuntimeException](CollectionTypesNELPacked.defaultInstance) + } + + "Non-empty types" should "fail parsing when fields are missing" in { + intercept[RuntimeException](CollectionTypesNEL.parseFrom(Array[Byte]())) + } + + "Non-empty types" should "succeed when all types are set " in { + val c1 = CollectionTypesNEL( + repeatedInt32 = NonEmptyList.of(1), + repeatedSint32 = NonEmptyList.of(2), + repeatedSfixed32 = NonEmptyList.of(3), + repeatedFixed32 = NonEmptyList.of(4), + repeatedUint32 = NonEmptyList.of(5), + repeatedInt64 = NonEmptyList.of(6), + repeatedSint64 = NonEmptyList.of(7), + repeatedSfixed64 = NonEmptyList.of(8), + repeatedFixed64 = NonEmptyList.of(9), + repeatedUint64 = NonEmptyList.of(10), + repeatedFloat = NonEmptyList.of(11), + repeatedDouble = NonEmptyList.of(12), + repeatedString = NonEmptyList.of("boo"), + repeatedBool = NonEmptyList.of(true), + repeatedBytes = NonEmptyList.of(com.google.protobuf.ByteString.EMPTY), + repeatedEnum = NonEmptyList.of(Enum.ONE), + repeatedMsg = NonEmptyList.of(SubMsg()), + repeatedFullname = NonEmptyList.of(FullName("X", "Y")), + ) + CollectionTypesNEL.parseFrom(c1.toByteArray) must be(c1) + CollectionTypesNEL.fromJavaProto(CollectionTypesNEL.toJavaProto(c1)) must be(c1) + } +} diff --git a/protobuf/scalapb/scalapb.proto b/protobuf/scalapb/scalapb.proto index 5bf2df013..16d7952ec 100644 --- a/protobuf/scalapb/scalapb.proto +++ b/protobuf/scalapb/scalapb.proto @@ -193,6 +193,22 @@ extend google.protobuf.MessageOptions { optional MessageOptions message = 1020; } +// Represents a custom Collection type in Scala. This allows ScalaPB to integrate with +// collection types that are different enough from the ones in the standard library. +message Collection { + // Type of the collection + optional string type = 1; + + // Set to true if this collection type is not allowed to be empty, for example + // cats.data.NonEmptyList. When true, ScalaPB will not generate `clearX` for the repeated + // field and not provide a default argument in the constructor. + optional bool non_empty = 2; + + // An Adapter is a Scala object available at runtime that provides certain static methods + // that can operate on this collection type. + optional string adapter = 3; +} + message FieldOptions { optional string type = 1; @@ -203,6 +219,8 @@ message FieldOptions { // to `scala.collection.Seq`. optional string collection_type = 3; + optional Collection collection = 8; + // If the field is a map, you can specify custom Scala types for the key // or value. optional string key_type = 4; diff --git a/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala b/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala index 6516445b7..ae4b1886d 100644 --- a/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala +++ b/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala @@ -178,7 +178,7 @@ object GeneratedCodeInfo extends scalapb.GeneratedMessageCompanion[com.google.pr private[this] var __serializedSizeCachedValue: _root_.scala.Int = 0 private[this] def __computeSerializedValue(): _root_.scala.Int = { var __size = 0 - if(path.nonEmpty) { + if (path.nonEmpty) { val __localsize = pathSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } diff --git a/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala b/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala index 35fb8b3ba..addb2ee33 100644 --- a/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala +++ b/scalapb-runtime/jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala @@ -294,11 +294,11 @@ object SourceCodeInfo extends scalapb.GeneratedMessageCompanion[com.google.proto private[this] var __serializedSizeCachedValue: _root_.scala.Int = 0 private[this] def __computeSerializedValue(): _root_.scala.Int = { var __size = 0 - if(path.nonEmpty) { + if (path.nonEmpty) { val __localsize = pathSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } - if(span.nonEmpty) { + if (span.nonEmpty) { val __localsize = spanSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } diff --git a/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala b/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala index d980662f4..23f8c66f3 100644 --- a/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala +++ b/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/GeneratedCodeInfo.scala @@ -169,7 +169,7 @@ object GeneratedCodeInfo extends scalapb.GeneratedMessageCompanion[com.google.pr private[this] var __serializedSizeCachedValue: _root_.scala.Int = 0 private[this] def __computeSerializedValue(): _root_.scala.Int = { var __size = 0 - if(path.nonEmpty) { + if (path.nonEmpty) { val __localsize = pathSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } diff --git a/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala b/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala index bb20d348f..b6b213bdc 100644 --- a/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala +++ b/scalapb-runtime/non-jvm/src/main/scala/com/google/protobuf/descriptor/SourceCodeInfo.scala @@ -285,11 +285,11 @@ object SourceCodeInfo extends scalapb.GeneratedMessageCompanion[com.google.proto private[this] var __serializedSizeCachedValue: _root_.scala.Int = 0 private[this] def __computeSerializedValue(): _root_.scala.Int = { var __size = 0 - if(path.nonEmpty) { + if (path.nonEmpty) { val __localsize = pathSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } - if(span.nonEmpty) { + if (span.nonEmpty) { val __localsize = spanSerializedSize __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__localsize) + __localsize } diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/options/Collection.scala b/scalapb-runtime/shared/src/main/scala/scalapb/options/Collection.scala new file mode 100644 index 000000000..432f126dc --- /dev/null +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/Collection.scala @@ -0,0 +1,196 @@ +// Generated by the Scala Plugin for the Protocol Buffer Compiler. +// Do not edit! +// +// Protofile syntax: PROTO2 + +package scalapb.options + +/** Represents a custom Collection type in Scala. This allows ScalaPB to integrate with + * collection types that are different enough from the ones in the standard library. + * + * @param type + * Type of the collection + * @param nonEmpty + * Set to true if this collection type is not allowed to be empty, for example + * cats.data.NonEmptyList. When true, ScalaPB will not generate `clearX` for the repeated + * field and not provide a default argument in the constructor. + * @param adapter + * An Adapter is a Scala object available at runtime that provides certain static methods + * that can operate on this collection type. + */ +@SerialVersionUID(0L) +final case class Collection( + `type`: _root_.scala.Option[_root_.scala.Predef.String] = _root_.scala.None, + nonEmpty: _root_.scala.Option[_root_.scala.Boolean] = _root_.scala.None, + adapter: _root_.scala.Option[_root_.scala.Predef.String] = _root_.scala.None, + unknownFields: _root_.scalapb.UnknownFieldSet = _root_.scalapb.UnknownFieldSet.empty + ) extends scalapb.GeneratedMessage with scalapb.lenses.Updatable[Collection] { + @transient + private[this] var __serializedSizeCachedValue: _root_.scala.Int = 0 + private[this] def __computeSerializedValue(): _root_.scala.Int = { + var __size = 0 + if (`type`.isDefined) { + val __value = `type`.get + __size += _root_.com.google.protobuf.CodedOutputStream.computeStringSize(1, __value) + }; + if (nonEmpty.isDefined) { + val __value = nonEmpty.get + __size += _root_.com.google.protobuf.CodedOutputStream.computeBoolSize(2, __value) + }; + if (adapter.isDefined) { + val __value = adapter.get + __size += _root_.com.google.protobuf.CodedOutputStream.computeStringSize(3, __value) + }; + __size += unknownFields.serializedSize + __size + } + override def serializedSize: _root_.scala.Int = { + var read = __serializedSizeCachedValue + if (read == 0) { + read = __computeSerializedValue() + __serializedSizeCachedValue = read + } + read + } + def writeTo(`_output__`: _root_.com.google.protobuf.CodedOutputStream): _root_.scala.Unit = { + `type`.foreach { __v => + val __m = __v + _output__.writeString(1, __m) + }; + nonEmpty.foreach { __v => + val __m = __v + _output__.writeBool(2, __m) + }; + adapter.foreach { __v => + val __m = __v + _output__.writeString(3, __m) + }; + unknownFields.writeTo(_output__) + } + def getType: _root_.scala.Predef.String = `type`.getOrElse("") + def clearType: Collection = copy(`type` = _root_.scala.None) + def withType(__v: _root_.scala.Predef.String): Collection = copy(`type` = Option(__v)) + def getNonEmpty: _root_.scala.Boolean = nonEmpty.getOrElse(false) + def clearNonEmpty: Collection = copy(nonEmpty = _root_.scala.None) + def withNonEmpty(__v: _root_.scala.Boolean): Collection = copy(nonEmpty = Option(__v)) + def getAdapter: _root_.scala.Predef.String = adapter.getOrElse("") + def clearAdapter: Collection = copy(adapter = _root_.scala.None) + def withAdapter(__v: _root_.scala.Predef.String): Collection = copy(adapter = Option(__v)) + def withUnknownFields(__v: _root_.scalapb.UnknownFieldSet) = copy(unknownFields = __v) + def discardUnknownFields = copy(unknownFields = _root_.scalapb.UnknownFieldSet.empty) + def getFieldByNumber(__fieldNumber: _root_.scala.Int): _root_.scala.Any = { + (__fieldNumber: @_root_.scala.unchecked) match { + case 1 => `type`.orNull + case 2 => nonEmpty.orNull + case 3 => adapter.orNull + } + } + def getField(__field: _root_.scalapb.descriptors.FieldDescriptor): _root_.scalapb.descriptors.PValue = { + _root_.scala.Predef.require(__field.containingMessage eq companion.scalaDescriptor) + (__field.number: @_root_.scala.unchecked) match { + case 1 => `type`.map(_root_.scalapb.descriptors.PString).getOrElse(_root_.scalapb.descriptors.PEmpty) + case 2 => nonEmpty.map(_root_.scalapb.descriptors.PBoolean).getOrElse(_root_.scalapb.descriptors.PEmpty) + case 3 => adapter.map(_root_.scalapb.descriptors.PString).getOrElse(_root_.scalapb.descriptors.PEmpty) + } + } + def toProtoString: _root_.scala.Predef.String = _root_.scalapb.TextFormat.printToUnicodeString(this) + def companion = scalapb.options.Collection +} + +object Collection extends scalapb.GeneratedMessageCompanion[scalapb.options.Collection] { + implicit def messageCompanion: scalapb.GeneratedMessageCompanion[scalapb.options.Collection] = this + def merge(`_message__`: scalapb.options.Collection, `_input__`: _root_.com.google.protobuf.CodedInputStream): scalapb.options.Collection = newBuilder(_message__).merge(_input__).result() + implicit def messageReads: _root_.scalapb.descriptors.Reads[scalapb.options.Collection] = _root_.scalapb.descriptors.Reads{ + case _root_.scalapb.descriptors.PMessage(__fieldsMap) => + _root_.scala.Predef.require(__fieldsMap.keys.forall(_.containingMessage == scalaDescriptor), "FieldDescriptor does not match message type.") + scalapb.options.Collection( + `type` = __fieldsMap.get(scalaDescriptor.findFieldByNumber(1).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Predef.String]]), + nonEmpty = __fieldsMap.get(scalaDescriptor.findFieldByNumber(2).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Boolean]]), + adapter = __fieldsMap.get(scalaDescriptor.findFieldByNumber(3).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Predef.String]]) + ) + case _ => throw new RuntimeException("Expected PMessage") + } + def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(2) + def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(2) + def messageCompanionForFieldNumber(__number: _root_.scala.Int): _root_.scalapb.GeneratedMessageCompanion[_] = throw new MatchError(__number) + lazy val nestedMessagesCompanions: Seq[_root_.scalapb.GeneratedMessageCompanion[_ <: _root_.scalapb.GeneratedMessage]] = Seq.empty + def enumCompanionForFieldNumber(__fieldNumber: _root_.scala.Int): _root_.scalapb.GeneratedEnumCompanion[_] = throw new MatchError(__fieldNumber) + lazy val defaultInstance = scalapb.options.Collection( + `type` = _root_.scala.None, + nonEmpty = _root_.scala.None, + adapter = _root_.scala.None + ) + final class Builder private ( + private var __type: _root_.scala.Option[_root_.scala.Predef.String], + private var __nonEmpty: _root_.scala.Option[_root_.scala.Boolean], + private var __adapter: _root_.scala.Option[_root_.scala.Predef.String], + private var `_unknownFields__`: _root_.scalapb.UnknownFieldSet.Builder + ) extends _root_.scalapb.MessageBuilder[scalapb.options.Collection] { + def merge(`_input__`: _root_.com.google.protobuf.CodedInputStream): this.type = { + var _done__ = false + while (!_done__) { + val _tag__ = _input__.readTag() + _tag__ match { + case 0 => _done__ = true + case 10 => + __type = Option(_input__.readStringRequireUtf8()) + case 16 => + __nonEmpty = Option(_input__.readBool()) + case 26 => + __adapter = Option(_input__.readStringRequireUtf8()) + case tag => + if (_unknownFields__ == null) { + _unknownFields__ = new _root_.scalapb.UnknownFieldSet.Builder() + } + _unknownFields__.parseField(tag, _input__) + } + } + this + } + def result(): scalapb.options.Collection = { + scalapb.options.Collection( + `type` = __type, + nonEmpty = __nonEmpty, + adapter = __adapter, + unknownFields = if (_unknownFields__ == null) _root_.scalapb.UnknownFieldSet.empty else _unknownFields__.result() + ) + } + } + object Builder extends _root_.scalapb.MessageBuilderCompanion[scalapb.options.Collection, scalapb.options.Collection.Builder] { + def apply(): Builder = new Builder( + __type = _root_.scala.None, + __nonEmpty = _root_.scala.None, + __adapter = _root_.scala.None, + `_unknownFields__` = null + ) + def apply(`_message__`: scalapb.options.Collection): Builder = new Builder( + __type = _message__.`type`, + __nonEmpty = _message__.nonEmpty, + __adapter = _message__.adapter, + `_unknownFields__` = new _root_.scalapb.UnknownFieldSet.Builder(_message__.unknownFields) + ) + } + def newBuilder: Builder = scalapb.options.Collection.Builder() + def newBuilder(a: scalapb.options.Collection): Builder = scalapb.options.Collection.Builder(a) + implicit class CollectionLens[UpperPB](_l: _root_.scalapb.lenses.Lens[UpperPB, scalapb.options.Collection]) extends _root_.scalapb.lenses.ObjectLens[UpperPB, scalapb.options.Collection](_l) { + def `type`: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Predef.String] = field(_.getType)((c_, f_) => c_.copy(`type` = Option(f_))) + def optionalType: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Option[_root_.scala.Predef.String]] = field(_.`type`)((c_, f_) => c_.copy(`type` = f_)) + def nonEmpty: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Boolean] = field(_.getNonEmpty)((c_, f_) => c_.copy(nonEmpty = Option(f_))) + def optionalNonEmpty: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Option[_root_.scala.Boolean]] = field(_.nonEmpty)((c_, f_) => c_.copy(nonEmpty = f_)) + def adapter: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Predef.String] = field(_.getAdapter)((c_, f_) => c_.copy(adapter = Option(f_))) + def optionalAdapter: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Option[_root_.scala.Predef.String]] = field(_.adapter)((c_, f_) => c_.copy(adapter = f_)) + } + final val TYPE_FIELD_NUMBER = 1 + final val NON_EMPTY_FIELD_NUMBER = 2 + final val ADAPTER_FIELD_NUMBER = 3 + def of( + `type`: _root_.scala.Option[_root_.scala.Predef.String], + nonEmpty: _root_.scala.Option[_root_.scala.Boolean], + adapter: _root_.scala.Option[_root_.scala.Predef.String] + ): _root_.scalapb.options.Collection = _root_.scalapb.options.Collection( + `type`, + nonEmpty, + adapter + ) + // @@protoc_insertion_point(GeneratedMessageCompanion[scalapb.Collection]) +} diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumOptions.scala b/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumOptions.scala index 8d1845fe9..8ba092d9a 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumOptions.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumOptions.scala @@ -107,8 +107,8 @@ object EnumOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Enu ) case _ => throw new RuntimeException("Expected PMessage") } - def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(3) - def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(3) + def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(4) + def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(4) def messageCompanionForFieldNumber(__number: _root_.scala.Int): _root_.scalapb.GeneratedMessageCompanion[_] = throw new MatchError(__number) lazy val nestedMessagesCompanions: Seq[_root_.scalapb.GeneratedMessageCompanion[_ <: _root_.scalapb.GeneratedMessage]] = Seq.empty def enumCompanionForFieldNumber(__fieldNumber: _root_.scala.Int): _root_.scalapb.GeneratedEnumCompanion[_] = throw new MatchError(__fieldNumber) diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumValueOptions.scala b/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumValueOptions.scala index 3b0726bfe..ada05ffb3 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumValueOptions.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/EnumValueOptions.scala @@ -88,8 +88,8 @@ object EnumValueOptions extends scalapb.GeneratedMessageCompanion[scalapb.option ) case _ => throw new RuntimeException("Expected PMessage") } - def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(4) - def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(4) + def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(5) + def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(5) def messageCompanionForFieldNumber(__number: _root_.scala.Int): _root_.scalapb.GeneratedMessageCompanion[_] = throw new MatchError(__number) lazy val nestedMessagesCompanions: Seq[_root_.scalapb.GeneratedMessageCompanion[_ <: _root_.scalapb.GeneratedMessage]] = Seq.empty def enumCompanionForFieldNumber(__fieldNumber: _root_.scala.Int): _root_.scalapb.GeneratedEnumCompanion[_] = throw new MatchError(__fieldNumber) diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/options/FieldOptions.scala b/scalapb-runtime/shared/src/main/scala/scalapb/options/FieldOptions.scala index 901233ab9..93c3091ac 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/options/FieldOptions.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/FieldOptions.scala @@ -26,6 +26,7 @@ final case class FieldOptions( `type`: _root_.scala.Option[_root_.scala.Predef.String] = _root_.scala.None, scalaName: _root_.scala.Option[_root_.scala.Predef.String] = _root_.scala.None, collectionType: _root_.scala.Option[_root_.scala.Predef.String] = _root_.scala.None, + collection: _root_.scala.Option[scalapb.options.Collection] = _root_.scala.None, keyType: _root_.scala.Option[_root_.scala.Predef.String] = _root_.scala.None, valueType: _root_.scala.Option[_root_.scala.Predef.String] = _root_.scala.None, annotations: _root_.scala.Seq[_root_.scala.Predef.String] = _root_.scala.Seq.empty, @@ -49,6 +50,10 @@ final case class FieldOptions( val __value = collectionType.get __size += _root_.com.google.protobuf.CodedOutputStream.computeStringSize(3, __value) }; + if (collection.isDefined) { + val __value = collection.get + __size += 1 + _root_.com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(__value.serializedSize) + __value.serializedSize + }; if (keyType.isDefined) { val __value = keyType.get __size += _root_.com.google.protobuf.CodedOutputStream.computeStringSize(4, __value) @@ -109,6 +114,12 @@ final case class FieldOptions( val __m = __v _output__.writeString(7, __m) }; + collection.foreach { __v => + val __m = __v + _output__.writeTag(8, 2) + _output__.writeUInt32NoTag(__m.serializedSize) + __m.writeTo(_output__) + }; noBox.foreach { __v => val __m = __v _output__.writeBool(30, __m) @@ -124,6 +135,9 @@ final case class FieldOptions( def getCollectionType: _root_.scala.Predef.String = collectionType.getOrElse("") def clearCollectionType: FieldOptions = copy(collectionType = _root_.scala.None) def withCollectionType(__v: _root_.scala.Predef.String): FieldOptions = copy(collectionType = Option(__v)) + def getCollection: scalapb.options.Collection = collection.getOrElse(scalapb.options.Collection.defaultInstance) + def clearCollection: FieldOptions = copy(collection = _root_.scala.None) + def withCollection(__v: scalapb.options.Collection): FieldOptions = copy(collection = Option(__v)) def getKeyType: _root_.scala.Predef.String = keyType.getOrElse("") def clearKeyType: FieldOptions = copy(keyType = _root_.scala.None) def withKeyType(__v: _root_.scala.Predef.String): FieldOptions = copy(keyType = Option(__v)) @@ -147,6 +161,7 @@ final case class FieldOptions( case 1 => `type`.orNull case 2 => scalaName.orNull case 3 => collectionType.orNull + case 8 => collection.orNull case 4 => keyType.orNull case 5 => valueType.orNull case 6 => annotations @@ -160,6 +175,7 @@ final case class FieldOptions( case 1 => `type`.map(_root_.scalapb.descriptors.PString).getOrElse(_root_.scalapb.descriptors.PEmpty) case 2 => scalaName.map(_root_.scalapb.descriptors.PString).getOrElse(_root_.scalapb.descriptors.PEmpty) case 3 => collectionType.map(_root_.scalapb.descriptors.PString).getOrElse(_root_.scalapb.descriptors.PEmpty) + case 8 => collection.map(_.toPMessage).getOrElse(_root_.scalapb.descriptors.PEmpty) case 4 => keyType.map(_root_.scalapb.descriptors.PString).getOrElse(_root_.scalapb.descriptors.PEmpty) case 5 => valueType.map(_root_.scalapb.descriptors.PString).getOrElse(_root_.scalapb.descriptors.PEmpty) case 6 => _root_.scalapb.descriptors.PRepeated(annotations.iterator.map(_root_.scalapb.descriptors.PString).toVector) @@ -181,6 +197,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi `type` = __fieldsMap.get(scalaDescriptor.findFieldByNumber(1).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Predef.String]]), scalaName = __fieldsMap.get(scalaDescriptor.findFieldByNumber(2).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Predef.String]]), collectionType = __fieldsMap.get(scalaDescriptor.findFieldByNumber(3).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Predef.String]]), + collection = __fieldsMap.get(scalaDescriptor.findFieldByNumber(8).get).flatMap(_.as[_root_.scala.Option[scalapb.options.Collection]]), keyType = __fieldsMap.get(scalaDescriptor.findFieldByNumber(4).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Predef.String]]), valueType = __fieldsMap.get(scalaDescriptor.findFieldByNumber(5).get).flatMap(_.as[_root_.scala.Option[_root_.scala.Predef.String]]), annotations = __fieldsMap.get(scalaDescriptor.findFieldByNumber(6).get).map(_.as[_root_.scala.Seq[_root_.scala.Predef.String]]).getOrElse(_root_.scala.Seq.empty), @@ -189,15 +206,22 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi ) case _ => throw new RuntimeException("Expected PMessage") } - def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(2) - def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(2) - def messageCompanionForFieldNumber(__number: _root_.scala.Int): _root_.scalapb.GeneratedMessageCompanion[_] = throw new MatchError(__number) + def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(3) + def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(3) + def messageCompanionForFieldNumber(__number: _root_.scala.Int): _root_.scalapb.GeneratedMessageCompanion[_] = { + var __out: _root_.scalapb.GeneratedMessageCompanion[_] = null + (__number: @_root_.scala.unchecked) match { + case 8 => __out = scalapb.options.Collection + } + __out + } lazy val nestedMessagesCompanions: Seq[_root_.scalapb.GeneratedMessageCompanion[_ <: _root_.scalapb.GeneratedMessage]] = Seq.empty def enumCompanionForFieldNumber(__fieldNumber: _root_.scala.Int): _root_.scalapb.GeneratedEnumCompanion[_] = throw new MatchError(__fieldNumber) lazy val defaultInstance = scalapb.options.FieldOptions( `type` = _root_.scala.None, scalaName = _root_.scala.None, collectionType = _root_.scala.None, + collection = _root_.scala.None, keyType = _root_.scala.None, valueType = _root_.scala.None, annotations = _root_.scala.Seq.empty, @@ -208,6 +232,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi private var __type: _root_.scala.Option[_root_.scala.Predef.String], private var __scalaName: _root_.scala.Option[_root_.scala.Predef.String], private var __collectionType: _root_.scala.Option[_root_.scala.Predef.String], + private var __collection: _root_.scala.Option[scalapb.options.Collection], private var __keyType: _root_.scala.Option[_root_.scala.Predef.String], private var __valueType: _root_.scala.Option[_root_.scala.Predef.String], private var __annotations: collection.mutable.Builder[_root_.scala.Predef.String, _root_.scala.Seq[_root_.scala.Predef.String]], @@ -227,6 +252,8 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi __scalaName = Option(_input__.readStringRequireUtf8()) case 26 => __collectionType = Option(_input__.readStringRequireUtf8()) + case 66 => + __collection = Option(_root_.scalapb.LiteParser.readMessage(_input__, __collection.getOrElse(scalapb.options.Collection.defaultInstance))) case 34 => __keyType = Option(_input__.readStringRequireUtf8()) case 42 => @@ -251,6 +278,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi `type` = __type, scalaName = __scalaName, collectionType = __collectionType, + collection = __collection, keyType = __keyType, valueType = __valueType, annotations = __annotations.result(), @@ -265,6 +293,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi __type = _root_.scala.None, __scalaName = _root_.scala.None, __collectionType = _root_.scala.None, + __collection = _root_.scala.None, __keyType = _root_.scala.None, __valueType = _root_.scala.None, __annotations = _root_.scala.collection.immutable.Vector.newBuilder[_root_.scala.Predef.String], @@ -276,6 +305,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi __type = _message__.`type`, __scalaName = _message__.scalaName, __collectionType = _message__.collectionType, + __collection = _message__.collection, __keyType = _message__.keyType, __valueType = _message__.valueType, __annotations = _root_.scala.collection.immutable.Vector.newBuilder[_root_.scala.Predef.String] ++= _message__.annotations, @@ -293,6 +323,8 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi def optionalScalaName: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Option[_root_.scala.Predef.String]] = field(_.scalaName)((c_, f_) => c_.copy(scalaName = f_)) def collectionType: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Predef.String] = field(_.getCollectionType)((c_, f_) => c_.copy(collectionType = Option(f_))) def optionalCollectionType: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Option[_root_.scala.Predef.String]] = field(_.collectionType)((c_, f_) => c_.copy(collectionType = f_)) + def collection: _root_.scalapb.lenses.Lens[UpperPB, scalapb.options.Collection] = field(_.getCollection)((c_, f_) => c_.copy(collection = Option(f_))) + def optionalCollection: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Option[scalapb.options.Collection]] = field(_.collection)((c_, f_) => c_.copy(collection = f_)) def keyType: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Predef.String] = field(_.getKeyType)((c_, f_) => c_.copy(keyType = Option(f_))) def optionalKeyType: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Option[_root_.scala.Predef.String]] = field(_.keyType)((c_, f_) => c_.copy(keyType = f_)) def valueType: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.Predef.String] = field(_.getValueType)((c_, f_) => c_.copy(valueType = Option(f_))) @@ -306,6 +338,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi final val TYPE_FIELD_NUMBER = 1 final val SCALA_NAME_FIELD_NUMBER = 2 final val COLLECTION_TYPE_FIELD_NUMBER = 3 + final val COLLECTION_FIELD_NUMBER = 8 final val KEY_TYPE_FIELD_NUMBER = 4 final val VALUE_TYPE_FIELD_NUMBER = 5 final val ANNOTATIONS_FIELD_NUMBER = 6 @@ -315,6 +348,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi `type`: _root_.scala.Option[_root_.scala.Predef.String], scalaName: _root_.scala.Option[_root_.scala.Predef.String], collectionType: _root_.scala.Option[_root_.scala.Predef.String], + collection: _root_.scala.Option[scalapb.options.Collection], keyType: _root_.scala.Option[_root_.scala.Predef.String], valueType: _root_.scala.Option[_root_.scala.Predef.String], annotations: _root_.scala.Seq[_root_.scala.Predef.String], @@ -324,6 +358,7 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi `type`, scalaName, collectionType, + collection, keyType, valueType, annotations, diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/options/OneofOptions.scala b/scalapb-runtime/shared/src/main/scala/scalapb/options/OneofOptions.scala index 49fbb1b75..84d91968c 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/options/OneofOptions.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/OneofOptions.scala @@ -71,8 +71,8 @@ object OneofOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.On ) case _ => throw new RuntimeException("Expected PMessage") } - def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(5) - def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(5) + def javaDescriptor: _root_.com.google.protobuf.Descriptors.Descriptor = ScalapbProto.javaDescriptor.getMessageTypes.get(6) + def scalaDescriptor: _root_.scalapb.descriptors.Descriptor = ScalapbProto.scalaDescriptor.messages(6) def messageCompanionForFieldNumber(__number: _root_.scala.Int): _root_.scalapb.GeneratedMessageCompanion[_] = throw new MatchError(__number) lazy val nestedMessagesCompanions: Seq[_root_.scalapb.GeneratedMessageCompanion[_ <: _root_.scalapb.GeneratedMessage]] = Seq.empty def enumCompanionForFieldNumber(__fieldNumber: _root_.scala.Int): _root_.scalapb.GeneratedEnumCompanion[_] = throw new MatchError(__fieldNumber) diff --git a/scalapb-runtime/shared/src/main/scala/scalapb/options/ScalapbProto.scala b/scalapb-runtime/shared/src/main/scala/scalapb/options/ScalapbProto.scala index 1ebda3785..7d54fdc97 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/options/ScalapbProto.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/ScalapbProto.scala @@ -13,6 +13,7 @@ object ScalapbProto extends _root_.scalapb.GeneratedFileObject { Seq[_root_.scalapb.GeneratedMessageCompanion[_ <: _root_.scalapb.GeneratedMessage]]( scalapb.options.ScalaPbOptions, scalapb.options.MessageOptions, + scalapb.options.Collection, scalapb.options.FieldOptions, scalapb.options.EnumOptions, scalapb.options.EnumValueOptions, @@ -55,24 +56,26 @@ object ScalapbProto extends _root_.scalapb.GeneratedFileObject { hRjb21wYW5pb25Bbm5vdGF0aW9ucxJJChRzZWFsZWRfb25lb2ZfZXh0ZW5kcxgGIAMoCUIX4j8UEhJzZWFsZWRPbmVvZkV4dGVuZ HNSEnNlYWxlZE9uZW9mRXh0ZW5kcxIhCgZub19ib3gYByABKAhCCuI/BxIFbm9Cb3hSBW5vQm94ElsKGnVua25vd25fZmllbGRzX 2Fubm90YXRpb25zGAggAygJQh3iPxoSGHVua25vd25GaWVsZHNBbm5vdGF0aW9uc1IYdW5rbm93bkZpZWxkc0Fubm90YXRpb25zK - gkIkE4QgICAgAIi/QIKDEZpZWxkT3B0aW9ucxIdCgR0eXBlGAEgASgJQgniPwYSBHR5cGVSBHR5cGUSLQoKc2NhbGFfbmFtZRgCI - AEoCUIO4j8LEglzY2FsYU5hbWVSCXNjYWxhTmFtZRI8Cg9jb2xsZWN0aW9uX3R5cGUYAyABKAlCE+I/EBIOY29sbGVjdGlvblR5c - GVSDmNvbGxlY3Rpb25UeXBlEicKCGtleV90eXBlGAQgASgJQgziPwkSB2tleVR5cGVSB2tleVR5cGUSLQoKdmFsdWVfdHlwZRgFI - AEoCUIO4j8LEgl2YWx1ZVR5cGVSCXZhbHVlVHlwZRIyCgthbm5vdGF0aW9ucxgGIAMoCUIQ4j8NEgthbm5vdGF0aW9uc1ILYW5ub - 3RhdGlvbnMSJwoIbWFwX3R5cGUYByABKAlCDOI/CRIHbWFwVHlwZVIHbWFwVHlwZRIhCgZub19ib3gYHiABKAhCCuI/BxIFbm9Cb - 3hSBW5vQm94KgkIkE4QgICAgAIiowEKC0VudW1PcHRpb25zEiYKB2V4dGVuZHMYASADKAlCDOI/CRIHZXh0ZW5kc1IHZXh0ZW5kc - xJCChFjb21wYW5pb25fZXh0ZW5kcxgCIAMoCUIV4j8SEhBjb21wYW5pb25FeHRlbmRzUhBjb21wYW5pb25FeHRlbmRzEh0KBHR5c - GUYAyABKAlCCeI/BhIEdHlwZVIEdHlwZSoJCJBOEICAgIACInQKEEVudW1WYWx1ZU9wdGlvbnMSJgoHZXh0ZW5kcxgBIAMoCUIM4 - j8JEgdleHRlbmRzUgdleHRlbmRzEi0KCnNjYWxhX25hbWUYAiABKAlCDuI/CxIJc2NhbGFOYW1lUglzY2FsYU5hbWUqCQiQThCAg - ICAAiJBCgxPbmVvZk9wdGlvbnMSJgoHZXh0ZW5kcxgBIAMoCUIM4j8JEgdleHRlbmRzUgdleHRlbmRzKgkIkE4QgICAgAI6UAoHb - 3B0aW9ucxIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxj8ByABKAsyFy5zY2FsYXBiLlNjYWxhUGJPcHRpb25zUgdvcHRpb - 25zOlMKB21lc3NhZ2USHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMY/AcgASgLMhcuc2NhbGFwYi5NZXNzYWdlT3B0a - W9uc1IHbWVzc2FnZTpLCgVmaWVsZBIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY/AcgASgLMhUuc2NhbGFwYi5GaWVsZ - E9wdGlvbnNSBWZpZWxkOlYKDGVudW1fb3B0aW9ucxIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxj8ByABKAsyFC5zY2FsY - XBiLkVudW1PcHRpb25zUgtlbnVtT3B0aW9uczpcCgplbnVtX3ZhbHVlEiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvb - nMY/AcgASgLMhkuc2NhbGFwYi5FbnVtVmFsdWVPcHRpb25zUgllbnVtVmFsdWU6SwoFb25lb2YSHS5nb29nbGUucHJvdG9idWYuT - 25lb2ZPcHRpb25zGPwHIAEoCzIVLnNjYWxhcGIuT25lb2ZPcHRpb25zUgVvbmVvZkInCg9zY2FsYXBiLm9wdGlvbnPiPxMKD3NjY - WxhcGIub3B0aW9ucxAB""" + gkIkE4QgICAgAIifwoKQ29sbGVjdGlvbhIdCgR0eXBlGAEgASgJQgniPwYSBHR5cGVSBHR5cGUSKgoJbm9uX2VtcHR5GAIgASgIQ + g3iPwoSCG5vbkVtcHR5Ughub25FbXB0eRImCgdhZGFwdGVyGAMgASgJQgziPwkSB2FkYXB0ZXJSB2FkYXB0ZXIiwwMKDEZpZWxkT + 3B0aW9ucxIdCgR0eXBlGAEgASgJQgniPwYSBHR5cGVSBHR5cGUSLQoKc2NhbGFfbmFtZRgCIAEoCUIO4j8LEglzY2FsYU5hbWVSC + XNjYWxhTmFtZRI8Cg9jb2xsZWN0aW9uX3R5cGUYAyABKAlCE+I/EBIOY29sbGVjdGlvblR5cGVSDmNvbGxlY3Rpb25UeXBlEkQKC + mNvbGxlY3Rpb24YCCABKAsyEy5zY2FsYXBiLkNvbGxlY3Rpb25CD+I/DBIKY29sbGVjdGlvblIKY29sbGVjdGlvbhInCghrZXlfd + HlwZRgEIAEoCUIM4j8JEgdrZXlUeXBlUgdrZXlUeXBlEi0KCnZhbHVlX3R5cGUYBSABKAlCDuI/CxIJdmFsdWVUeXBlUgl2YWx1Z + VR5cGUSMgoLYW5ub3RhdGlvbnMYBiADKAlCEOI/DRILYW5ub3RhdGlvbnNSC2Fubm90YXRpb25zEicKCG1hcF90eXBlGAcgASgJQ + gziPwkSB21hcFR5cGVSB21hcFR5cGUSIQoGbm9fYm94GB4gASgIQgriPwcSBW5vQm94UgVub0JveCoJCJBOEICAgIACIqMBCgtFb + nVtT3B0aW9ucxImCgdleHRlbmRzGAEgAygJQgziPwkSB2V4dGVuZHNSB2V4dGVuZHMSQgoRY29tcGFuaW9uX2V4dGVuZHMYAiADK + AlCFeI/EhIQY29tcGFuaW9uRXh0ZW5kc1IQY29tcGFuaW9uRXh0ZW5kcxIdCgR0eXBlGAMgASgJQgniPwYSBHR5cGVSBHR5cGUqC + QiQThCAgICAAiJ0ChBFbnVtVmFsdWVPcHRpb25zEiYKB2V4dGVuZHMYASADKAlCDOI/CRIHZXh0ZW5kc1IHZXh0ZW5kcxItCgpzY + 2FsYV9uYW1lGAIgASgJQg7iPwsSCXNjYWxhTmFtZVIJc2NhbGFOYW1lKgkIkE4QgICAgAIiQQoMT25lb2ZPcHRpb25zEiYKB2V4d + GVuZHMYASADKAlCDOI/CRIHZXh0ZW5kc1IHZXh0ZW5kcyoJCJBOEICAgIACOlAKB29wdGlvbnMSHC5nb29nbGUucHJvdG9idWYuR + mlsZU9wdGlvbnMY/AcgASgLMhcuc2NhbGFwYi5TY2FsYVBiT3B0aW9uc1IHb3B0aW9uczpTCgdtZXNzYWdlEh8uZ29vZ2xlLnByb + 3RvYnVmLk1lc3NhZ2VPcHRpb25zGPwHIAEoCzIXLnNjYWxhcGIuTWVzc2FnZU9wdGlvbnNSB21lc3NhZ2U6SwoFZmllbGQSHS5nb + 29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGPwHIAEoCzIVLnNjYWxhcGIuRmllbGRPcHRpb25zUgVmaWVsZDpWCgxlbnVtX29wd + GlvbnMSHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMY/AcgASgLMhQuc2NhbGFwYi5FbnVtT3B0aW9uc1ILZW51bU9wdGlvb + nM6XAoKZW51bV92YWx1ZRIhLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zGPwHIAEoCzIZLnNjYWxhcGIuRW51bVZhb + HVlT3B0aW9uc1IJZW51bVZhbHVlOksKBW9uZW9mEh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9ucxj8ByABKAsyFS5zY2FsY + XBiLk9uZW9mT3B0aW9uc1IFb25lb2ZCJwoPc2NhbGFwYi5vcHRpb25z4j8TCg9zY2FsYXBiLm9wdGlvbnMQAQ==""" ).mkString) lazy val scalaDescriptor: _root_.scalapb.descriptors.FileDescriptor = { val scalaProto = com.google.protobuf.descriptor.FileDescriptorProto.parseFrom(ProtoBytes)