diff --git a/compiler-plugin/src/main/java/scalapb/options/compiler/Scalapb.java b/compiler-plugin/src/main/java/scalapb/options/compiler/Scalapb.java index 56b46d73a..0774155fd 100644 --- a/compiler-plugin/src/main/java/scalapb/options/compiler/Scalapb.java +++ b/compiler-plugin/src/main/java/scalapb/options/compiler/Scalapb.java @@ -3996,6 +3996,23 @@ public interface FieldOptionsOrBuilder extends */ com.google.protobuf.ByteString getAnnotationsBytes(int index); + + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + boolean hasNoBox(); + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + boolean getNoBox(); } /** * Protobuf type {@code scalapb.FieldOptions} @@ -4016,6 +4033,7 @@ private FieldOptions() { keyType_ = ""; valueType_ = ""; annotations_ = com.google.protobuf.LazyStringArrayList.EMPTY; + noBox_ = false; } @java.lang.Override @@ -4088,6 +4106,11 @@ private FieldOptions( annotations_.add(bs); break; } + case 240: { + bitField0_ |= 0x00000020; + noBox_ = input.readBool(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -4404,6 +4427,29 @@ public java.lang.String getAnnotations(int index) { return annotations_.getByteString(index); } + public static final int NO_BOX_FIELD_NUMBER = 30; + private boolean noBox_; + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + public boolean hasNoBox() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + public boolean getNoBox() { + return noBox_; + } + private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; @@ -4434,6 +4480,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) for (int i = 0; i < annotations_.size(); i++) { com.google.protobuf.GeneratedMessageV3.writeString(output, 6, annotations_.getRaw(i)); } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBool(30, noBox_); + } unknownFields.writeTo(output); } @@ -4465,6 +4514,10 @@ public int getSerializedSize() { size += dataSize; size += 1 * getAnnotationsList().size(); } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(30, noBox_); + } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; @@ -4508,6 +4561,11 @@ public boolean equals(final java.lang.Object obj) { } result = result && getAnnotationsList() .equals(other.getAnnotationsList()); + result = result && (hasNoBox() == other.hasNoBox()); + if (hasNoBox()) { + result = result && (getNoBox() + == other.getNoBox()); + } result = result && unknownFields.equals(other.unknownFields); return result; } @@ -4543,6 +4601,11 @@ public int hashCode() { hash = (37 * hash) + ANNOTATIONS_FIELD_NUMBER; hash = (53 * hash) + getAnnotationsList().hashCode(); } + if (hasNoBox()) { + hash = (37 * hash) + NO_BOX_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getNoBox()); + } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; @@ -4684,6 +4747,8 @@ public Builder clear() { bitField0_ = (bitField0_ & ~0x00000010); annotations_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000020); + noBox_ = false; + bitField0_ = (bitField0_ & ~0x00000040); return this; } @@ -4733,6 +4798,10 @@ public scalapb.options.compiler.Scalapb.FieldOptions buildPartial() { bitField0_ = (bitField0_ & ~0x00000020); } result.annotations_ = annotations_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000020; + } + result.noBox_ = noBox_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -4810,6 +4879,9 @@ public Builder mergeFrom(scalapb.options.compiler.Scalapb.FieldOptions other) { } onChanged(); } + if (other.hasNoBox()) { + setNoBox(other.getNoBox()); + } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -5412,6 +5484,54 @@ public Builder addAnnotationsBytes( onChanged(); return this; } + + private boolean noBox_ ; + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public boolean hasNoBox() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public boolean getNoBox() { + return noBox_; + } + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public Builder setNoBox(boolean value) { + bitField0_ |= 0x00000040; + noBox_ = value; + onChanged(); + return this; + } + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public Builder clearNoBox() { + bitField0_ = (bitField0_ & ~0x00000040); + noBox_ = false; + onChanged(); + return this; + } public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); @@ -8030,27 +8150,27 @@ public scalapb.options.compiler.Scalapb.OneofOptions getDefaultInstanceForType() "rsions\030\241\215\006 \001(\010\"~\n\016MessageOptions\022\017\n\007exte" + "nds\030\001 \003(\t\022\031\n\021companion_extends\030\002 \003(\t\022\023\n\013" + "annotations\030\003 \003(\t\022\014\n\004type\030\004 \001(\t\022\035\n\025compa" + - "nion_annotations\030\005 \003(\t\"\204\001\n\014FieldOptions\022" + + "nion_annotations\030\005 \003(\t\"\224\001\n\014FieldOptions\022" + "\014\n\004type\030\001 \001(\t\022\022\n\nscala_name\030\002 \001(\t\022\027\n\017col" + "lection_type\030\003 \001(\t\022\020\n\010key_type\030\004 \001(\t\022\022\n\n" + - "value_type\030\005 \001(\t\022\023\n\013annotations\030\006 \003(\t\"G\n" + - "\013EnumOptions\022\017\n\007extends\030\001 \003(\t\022\031\n\021compani" + - "on_extends\030\002 \003(\t\022\014\n\004type\030\003 \001(\t\"#\n\020EnumVa" + - "lueOptions\022\017\n\007extends\030\001 \003(\t\"\037\n\014OneofOpti" + - "ons\022\017\n\007extends\030\001 \003(\t:G\n\007options\022\034.google" + - ".protobuf.FileOptions\030\374\007 \001(\0132\027.scalapb.S" + - "calaPbOptions:J\n\007message\022\037.google.protob" + - "uf.MessageOptions\030\374\007 \001(\0132\027.scalapb.Messa" + - "geOptions:D\n\005field\022\035.google.protobuf.Fie" + - "ldOptions\030\374\007 \001(\0132\025.scalapb.FieldOptions:" + - "I\n\014enum_options\022\034.google.protobuf.EnumOp" + - "tions\030\374\007 \001(\0132\024.scalapb.EnumOptions:Q\n\nen" + - "um_value\022!.google.protobuf.EnumValueOpti" + - "ons\030\374\007 \001(\0132\031.scalapb.EnumValueOptions:D\n" + - "\005oneof\022\035.google.protobuf.OneofOptions\030\374\007" + - " \001(\0132\025.scalapb.OneofOptionsB9\n\030scalapb.o" + - "ptions.compiler\342?\034\n\030scalapb.options.comp" + - "iler\020\001" + "value_type\030\005 \001(\t\022\023\n\013annotations\030\006 \003(\t\022\016\n" + + "\006no_box\030\036 \001(\010\"G\n\013EnumOptions\022\017\n\007extends\030" + + "\001 \003(\t\022\031\n\021companion_extends\030\002 \003(\t\022\014\n\004type" + + "\030\003 \001(\t\"#\n\020EnumValueOptions\022\017\n\007extends\030\001 " + + "\003(\t\"\037\n\014OneofOptions\022\017\n\007extends\030\001 \003(\t:G\n\007" + + "options\022\034.google.protobuf.FileOptions\030\374\007" + + " \001(\0132\027.scalapb.ScalaPbOptions:J\n\007message" + + "\022\037.google.protobuf.MessageOptions\030\374\007 \001(\013" + + "2\027.scalapb.MessageOptions:D\n\005field\022\035.goo" + + "gle.protobuf.FieldOptions\030\374\007 \001(\0132\025.scala" + + "pb.FieldOptions:I\n\014enum_options\022\034.google" + + ".protobuf.EnumOptions\030\374\007 \001(\0132\024.scalapb.E" + + "numOptions:Q\n\nenum_value\022!.google.protob" + + "uf.EnumValueOptions\030\374\007 \001(\0132\031.scalapb.Enu" + + "mValueOptions:D\n\005oneof\022\035.google.protobuf" + + ".OneofOptions\030\374\007 \001(\0132\025.scalapb.OneofOpti" + + "onsB9\n\030scalapb.options.compiler\342?\034\n\030scal" + + "apb.options.compiler\020\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -8082,7 +8202,7 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( internal_static_scalapb_FieldOptions_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_scalapb_FieldOptions_descriptor, - new java.lang.String[] { "Type", "ScalaName", "CollectionType", "KeyType", "ValueType", "Annotations", }); + new java.lang.String[] { "Type", "ScalaName", "CollectionType", "KeyType", "ValueType", "Annotations", "NoBox", }); internal_static_scalapb_EnumOptions_descriptor = getDescriptor().getMessageTypes().get(3); internal_static_scalapb_EnumOptions_fieldAccessorTable = new diff --git a/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorPimps.scala b/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorPimps.scala index adccb9837..03be8d3a4 100644 --- a/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorPimps.scala +++ b/compiler-plugin/src/main/scala/scalapb/compiler/DescriptorPimps.scala @@ -107,11 +107,11 @@ trait DescriptorPimps { // Is this field boxed inside an Option in Scala. Equivalent, does the Java API // support hasX methods for this field. def supportsPresence: Boolean = - fd.isOptional && !fd.isInOneof && (!fd.getFile.isProto3 || fd.isMessage) + fd.isOptional && !fd.isInOneof && (!fd.getFile.isProto3 || fd.isMessage) && !fieldOptions.getNoBox - // Is the Scala representation of this field is a singular type. + // Is the Scala representation of this field a singular type. def isSingular = fd.isRequired || ( - fd.getFile.isProto3 && !fd.isInOneof && fd.isOptional && !fd.isMessage) + fd.getFile.isProto3 && !fd.isInOneof && fd.isOptional && !fd.isMessage) || (fieldOptions.getNoBox && fd.isOptional) def enclosingType: EnclosingType = if (isSingular) EnclosingType.None diff --git a/compiler-plugin/src/main/scala/scalapb/compiler/ProtoValidation.scala b/compiler-plugin/src/main/scala/scalapb/compiler/ProtoValidation.scala index a7379ee07..ee635984a 100644 --- a/compiler-plugin/src/main/scala/scalapb/compiler/ProtoValidation.scala +++ b/compiler-plugin/src/main/scala/scalapb/compiler/ProtoValidation.scala @@ -48,5 +48,8 @@ class ProtoValidation(val params: GeneratorParams) extends DescriptorPimps { if (fd.isMapField && fd.fieldOptions.hasType) throw new GeneratorException( s"${fd.getFullName}: Field ${fd.getName} is a map and has type specified. Use key_type or value_type instead.") + if (!fd.isOptional && fd.fieldOptions.hasNoBox) + throw new GeneratorException( + s"${fd.getFullName}: Field ${fd.getName} has no_box set but is not an optional field.") } } diff --git a/e2e/src/main/protobuf/no_box.proto b/e2e/src/main/protobuf/no_box.proto new file mode 100644 index 000000000..6872ae478 --- /dev/null +++ b/e2e/src/main/protobuf/no_box.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package com.trueaccord.proto.e2e; + +import "scalapb/scalapb.proto"; + +message Tyre { + int32 size = 1; +} + +message Car { + Tyre tyre1 = 1 [(scalapb.field).no_box = true]; + Tyre tyre2 = 2 [(scalapb.field).no_box = false]; +} \ No newline at end of file diff --git a/e2e/src/test/scala/NoBoxSpec.scala b/e2e/src/test/scala/NoBoxSpec.scala new file mode 100644 index 000000000..627bbf659 --- /dev/null +++ b/e2e/src/test/scala/NoBoxSpec.scala @@ -0,0 +1,39 @@ +import com.trueaccord.proto.e2e.NoBox +import com.trueaccord.proto.e2e.no_box.Car +import com.trueaccord.proto.e2e.no_box.Tyre +import org.scalatest._ + +class NoBoxSpec extends FlatSpec with MustMatchers { + val car = Car(tyre1 = Tyre(size = 10), tyre2 = Some(Tyre(size = 20))) + + "no_box" should "create correct methods" in { + car.tyre1 must be(Tyre(size = 10)) + car.tyre2 must be(Some(Tyre(size = 20))) + } + + "fields with no_box" should "parseFrom byte array correctly" in { + val serialized = car.toByteArray + Car.parseFrom(serialized) must be(car) + } + + "Scala representation of Java message with no_box field with default value" should "have that field with default value" in { + val javaCar = NoBox.Car.getDefaultInstance() + javaCar.hasTyre1 must be(false) + + val scalaCar = Car.parseFrom(javaCar.toByteArray) + scalaCar.tyre1 must be(Tyre.defaultInstance) + } + + "Java representation of Scala message with a no_box field with default value" should "not have that field" in { + val scalaCar = Car(tyre1 = Tyre.defaultInstance) + scalaCar.tyre1 must be(Tyre.defaultInstance) + + val javaCar = NoBox.Car.parseFrom(scalaCar.toByteArray) + javaCar.hasTyre1 must be(false) + } + + "Scala message with a no_box field with null value" should "throw exception when being serialized" in { + val car = Car(tyre1 = null) + a[NullPointerException] shouldBe thrownBy(car.toByteArray) + } +} \ No newline at end of file diff --git a/protobuf/scalapb/scalapb.proto b/protobuf/scalapb/scalapb.proto index 6c2b9c628..2f2a02cb9 100644 --- a/protobuf/scalapb/scalapb.proto +++ b/protobuf/scalapb/scalapb.proto @@ -105,6 +105,9 @@ message FieldOptions { // Custom annotations to add to the field. repeated string annotations = 6; + + // Do not box this value in Option[T] + optional bool no_box = 30; } extend google.protobuf.FieldOptions { diff --git a/scalapb-runtime/jvm/src/main/java/scalapb/options/Scalapb.java b/scalapb-runtime/jvm/src/main/java/scalapb/options/Scalapb.java index cbea039a0..2ac0a5c03 100644 --- a/scalapb-runtime/jvm/src/main/java/scalapb/options/Scalapb.java +++ b/scalapb-runtime/jvm/src/main/java/scalapb/options/Scalapb.java @@ -3996,6 +3996,23 @@ public interface FieldOptionsOrBuilder extends */ com.google.protobuf.ByteString getAnnotationsBytes(int index); + + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + boolean hasNoBox(); + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + boolean getNoBox(); } /** * Protobuf type {@code scalapb.FieldOptions} @@ -4016,6 +4033,7 @@ private FieldOptions() { keyType_ = ""; valueType_ = ""; annotations_ = com.google.protobuf.LazyStringArrayList.EMPTY; + noBox_ = false; } @java.lang.Override @@ -4088,6 +4106,11 @@ private FieldOptions( annotations_.add(bs); break; } + case 240: { + bitField0_ |= 0x00000020; + noBox_ = input.readBool(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -4404,6 +4427,29 @@ public java.lang.String getAnnotations(int index) { return annotations_.getByteString(index); } + public static final int NO_BOX_FIELD_NUMBER = 30; + private boolean noBox_; + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + public boolean hasNoBox() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + *
+     * Do not box this value in Option[T]
+     * 
+ * + * optional bool no_box = 30; + */ + public boolean getNoBox() { + return noBox_; + } + private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; @@ -4434,6 +4480,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) for (int i = 0; i < annotations_.size(); i++) { com.google.protobuf.GeneratedMessageV3.writeString(output, 6, annotations_.getRaw(i)); } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBool(30, noBox_); + } unknownFields.writeTo(output); } @@ -4465,6 +4514,10 @@ public int getSerializedSize() { size += dataSize; size += 1 * getAnnotationsList().size(); } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(30, noBox_); + } size += unknownFields.getSerializedSize(); memoizedSize = size; return size; @@ -4508,6 +4561,11 @@ public boolean equals(final java.lang.Object obj) { } result = result && getAnnotationsList() .equals(other.getAnnotationsList()); + result = result && (hasNoBox() == other.hasNoBox()); + if (hasNoBox()) { + result = result && (getNoBox() + == other.getNoBox()); + } result = result && unknownFields.equals(other.unknownFields); return result; } @@ -4543,6 +4601,11 @@ public int hashCode() { hash = (37 * hash) + ANNOTATIONS_FIELD_NUMBER; hash = (53 * hash) + getAnnotationsList().hashCode(); } + if (hasNoBox()) { + hash = (37 * hash) + NO_BOX_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getNoBox()); + } hash = (29 * hash) + unknownFields.hashCode(); memoizedHashCode = hash; return hash; @@ -4684,6 +4747,8 @@ public Builder clear() { bitField0_ = (bitField0_ & ~0x00000010); annotations_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000020); + noBox_ = false; + bitField0_ = (bitField0_ & ~0x00000040); return this; } @@ -4733,6 +4798,10 @@ public scalapb.options.Scalapb.FieldOptions buildPartial() { bitField0_ = (bitField0_ & ~0x00000020); } result.annotations_ = annotations_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000020; + } + result.noBox_ = noBox_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -4810,6 +4879,9 @@ public Builder mergeFrom(scalapb.options.Scalapb.FieldOptions other) { } onChanged(); } + if (other.hasNoBox()) { + setNoBox(other.getNoBox()); + } this.mergeUnknownFields(other.unknownFields); onChanged(); return this; @@ -5412,6 +5484,54 @@ public Builder addAnnotationsBytes( onChanged(); return this; } + + private boolean noBox_ ; + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public boolean hasNoBox() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public boolean getNoBox() { + return noBox_; + } + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public Builder setNoBox(boolean value) { + bitField0_ |= 0x00000040; + noBox_ = value; + onChanged(); + return this; + } + /** + *
+       * Do not box this value in Option[T]
+       * 
+ * + * optional bool no_box = 30; + */ + public Builder clearNoBox() { + bitField0_ = (bitField0_ & ~0x00000040); + noBox_ = false; + onChanged(); + return this; + } public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); @@ -8030,26 +8150,27 @@ public scalapb.options.Scalapb.OneofOptions getDefaultInstanceForType() { "va_conversions\030\241\215\006 \001(\010\"~\n\016MessageOptions" + "\022\017\n\007extends\030\001 \003(\t\022\031\n\021companion_extends\030\002" + " \003(\t\022\023\n\013annotations\030\003 \003(\t\022\014\n\004type\030\004 \001(\t\022" + - "\035\n\025companion_annotations\030\005 \003(\t\"\204\001\n\014Field" + + "\035\n\025companion_annotations\030\005 \003(\t\"\224\001\n\014Field" + "Options\022\014\n\004type\030\001 \001(\t\022\022\n\nscala_name\030\002 \001(" + "\t\022\027\n\017collection_type\030\003 \001(\t\022\020\n\010key_type\030\004" + " \001(\t\022\022\n\nvalue_type\030\005 \001(\t\022\023\n\013annotations\030" + - "\006 \003(\t\"G\n\013EnumOptions\022\017\n\007extends\030\001 \003(\t\022\031\n" + - "\021companion_extends\030\002 \003(\t\022\014\n\004type\030\003 \001(\t\"#" + - "\n\020EnumValueOptions\022\017\n\007extends\030\001 \003(\t\"\037\n\014O" + - "neofOptions\022\017\n\007extends\030\001 \003(\t:G\n\007options\022" + - "\034.google.protobuf.FileOptions\030\374\007 \001(\0132\027.s" + - "calapb.ScalaPbOptions:J\n\007message\022\037.googl" + - "e.protobuf.MessageOptions\030\374\007 \001(\0132\027.scala" + - "pb.MessageOptions:D\n\005field\022\035.google.prot" + - "obuf.FieldOptions\030\374\007 \001(\0132\025.scalapb.Field" + - "Options:I\n\014enum_options\022\034.google.protobu" + - "f.EnumOptions\030\374\007 \001(\0132\024.scalapb.EnumOptio" + - "ns:Q\n\nenum_value\022!.google.protobuf.EnumV" + - "alueOptions\030\374\007 \001(\0132\031.scalapb.EnumValueOp" + - "tions:D\n\005oneof\022\035.google.protobuf.OneofOp" + - "tions\030\374\007 \001(\0132\025.scalapb.OneofOptionsB\'\n\017s" + - "calapb.options\342?\023\n\017scalapb.options\020\001" + "\006 \003(\t\022\016\n\006no_box\030\036 \001(\010\"G\n\013EnumOptions\022\017\n\007" + + "extends\030\001 \003(\t\022\031\n\021companion_extends\030\002 \003(\t" + + "\022\014\n\004type\030\003 \001(\t\"#\n\020EnumValueOptions\022\017\n\007ex" + + "tends\030\001 \003(\t\"\037\n\014OneofOptions\022\017\n\007extends\030\001" + + " \003(\t:G\n\007options\022\034.google.protobuf.FileOp" + + "tions\030\374\007 \001(\0132\027.scalapb.ScalaPbOptions:J\n" + + "\007message\022\037.google.protobuf.MessageOption" + + "s\030\374\007 \001(\0132\027.scalapb.MessageOptions:D\n\005fie" + + "ld\022\035.google.protobuf.FieldOptions\030\374\007 \001(\013" + + "2\025.scalapb.FieldOptions:I\n\014enum_options\022" + + "\034.google.protobuf.EnumOptions\030\374\007 \001(\0132\024.s" + + "calapb.EnumOptions:Q\n\nenum_value\022!.googl" + + "e.protobuf.EnumValueOptions\030\374\007 \001(\0132\031.sca" + + "lapb.EnumValueOptions:D\n\005oneof\022\035.google." + + "protobuf.OneofOptions\030\374\007 \001(\0132\025.scalapb.O" + + "neofOptionsB\'\n\017scalapb.options\342?\023\n\017scala" + + "pb.options\020\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { @@ -8081,7 +8202,7 @@ public com.google.protobuf.ExtensionRegistry assignDescriptors( internal_static_scalapb_FieldOptions_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_scalapb_FieldOptions_descriptor, - new java.lang.String[] { "Type", "ScalaName", "CollectionType", "KeyType", "ValueType", "Annotations", }); + new java.lang.String[] { "Type", "ScalaName", "CollectionType", "KeyType", "ValueType", "Annotations", "NoBox", }); internal_static_scalapb_EnumOptions_descriptor = getDescriptor().getMessageTypes().get(3); internal_static_scalapb_EnumOptions_fieldAccessorTable = new 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 aa91b3684..d8887b9b3 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/options/FieldOptions.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/FieldOptions.scala @@ -14,6 +14,8 @@ package scalapb.options * or value. * @param annotations * Custom annotations to add to the field. + * @param noBox + * Do not box this value in Option[T] */ @SerialVersionUID(0L) final case class FieldOptions( @@ -22,7 +24,8 @@ final case class FieldOptions( collectionType: scala.Option[String] = None, keyType: scala.Option[String] = None, valueType: scala.Option[String] = None, - annotations: _root_.scala.collection.Seq[String] = _root_.scala.collection.Seq.empty + annotations: _root_.scala.collection.Seq[String] = _root_.scala.collection.Seq.empty, + noBox: scala.Option[Boolean] = None ) extends scalapb.GeneratedMessage with scalapb.Message[FieldOptions] with scalapb.lenses.Updatable[FieldOptions] { @transient private[this] var __serializedSizeCachedValue: Int = 0 @@ -34,6 +37,7 @@ final case class FieldOptions( if (keyType.isDefined) { __size += _root_.com.google.protobuf.CodedOutputStream.computeStringSize(4, keyType.get) } if (valueType.isDefined) { __size += _root_.com.google.protobuf.CodedOutputStream.computeStringSize(5, valueType.get) } annotations.foreach(annotations => __size += _root_.com.google.protobuf.CodedOutputStream.computeStringSize(6, annotations)) + if (noBox.isDefined) { __size += _root_.com.google.protobuf.CodedOutputStream.computeBoolSize(30, noBox.get) } __size } final override def serializedSize: Int = { @@ -63,6 +67,9 @@ final case class FieldOptions( annotations.foreach { __v => _output__.writeString(6, __v) }; + noBox.foreach { __v => + _output__.writeBool(30, __v) + }; } def mergeFrom(`_input__`: _root_.com.google.protobuf.CodedInputStream): scalapb.options.FieldOptions = { var __type = this.`type` @@ -71,6 +78,7 @@ final case class FieldOptions( var __keyType = this.keyType var __valueType = this.valueType val __annotations = (_root_.scala.collection.immutable.Vector.newBuilder[String] ++= this.annotations) + var __noBox = this.noBox var _done__ = false while (!_done__) { val _tag__ = _input__.readTag() @@ -88,6 +96,8 @@ final case class FieldOptions( __valueType = Some(_input__.readString()) case 50 => __annotations += _input__.readString() + case 240 => + __noBox = Some(_input__.readBool()) case tag => _input__.skipField(tag) } } @@ -97,7 +107,8 @@ final case class FieldOptions( collectionType = __collectionType, keyType = __keyType, valueType = __valueType, - annotations = __annotations.result() + annotations = __annotations.result(), + noBox = __noBox ) } def getType: String = `type`.getOrElse("") @@ -119,6 +130,9 @@ final case class FieldOptions( def addAnnotations(__vs: String*): FieldOptions = addAllAnnotations(__vs) def addAllAnnotations(__vs: TraversableOnce[String]): FieldOptions = copy(annotations = annotations ++ __vs) def withAnnotations(__v: _root_.scala.collection.Seq[String]): FieldOptions = copy(annotations = __v) + def getNoBox: Boolean = noBox.getOrElse(false) + def clearNoBox: FieldOptions = copy(noBox = None) + def withNoBox(__v: Boolean): FieldOptions = copy(noBox = Some(__v)) def getFieldByNumber(__fieldNumber: Int): scala.Any = { (__fieldNumber: @_root_.scala.unchecked) match { case 1 => `type`.orNull @@ -127,6 +141,7 @@ final case class FieldOptions( case 4 => keyType.orNull case 5 => valueType.orNull case 6 => annotations + case 30 => noBox.orNull } } def getField(__field: _root_.scalapb.descriptors.FieldDescriptor): _root_.scalapb.descriptors.PValue = { @@ -138,6 +153,7 @@ final case class FieldOptions( 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.map(_root_.scalapb.descriptors.PString)(_root_.scala.collection.breakOut)) + case 30 => noBox.map(_root_.scalapb.descriptors.PBoolean).getOrElse(_root_.scalapb.descriptors.PEmpty) } } def toProtoString: String = _root_.scalapb.TextFormat.printToUnicodeString(this) @@ -155,7 +171,8 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi __fieldsMap.get(__fields.get(2)).asInstanceOf[scala.Option[String]], __fieldsMap.get(__fields.get(3)).asInstanceOf[scala.Option[String]], __fieldsMap.get(__fields.get(4)).asInstanceOf[scala.Option[String]], - __fieldsMap.getOrElse(__fields.get(5), Nil).asInstanceOf[_root_.scala.collection.Seq[String]] + __fieldsMap.getOrElse(__fields.get(5), Nil).asInstanceOf[_root_.scala.collection.Seq[String]], + __fieldsMap.get(__fields.get(6)).asInstanceOf[scala.Option[Boolean]] ) } implicit def messageReads: _root_.scalapb.descriptors.Reads[scalapb.options.FieldOptions] = _root_.scalapb.descriptors.Reads{ @@ -167,7 +184,8 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi __fieldsMap.get(scalaDescriptor.findFieldByNumber(3).get).flatMap(_.as[scala.Option[String]]), __fieldsMap.get(scalaDescriptor.findFieldByNumber(4).get).flatMap(_.as[scala.Option[String]]), __fieldsMap.get(scalaDescriptor.findFieldByNumber(5).get).flatMap(_.as[scala.Option[String]]), - __fieldsMap.get(scalaDescriptor.findFieldByNumber(6).get).map(_.as[_root_.scala.collection.Seq[String]]).getOrElse(_root_.scala.collection.Seq.empty) + __fieldsMap.get(scalaDescriptor.findFieldByNumber(6).get).map(_.as[_root_.scala.collection.Seq[String]]).getOrElse(_root_.scala.collection.Seq.empty), + __fieldsMap.get(scalaDescriptor.findFieldByNumber(30).get).flatMap(_.as[scala.Option[Boolean]]) ) case _ => throw new RuntimeException("Expected PMessage") } @@ -190,6 +208,8 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi def valueType: _root_.scalapb.lenses.Lens[UpperPB, String] = field(_.getValueType)((c_, f_) => c_.copy(valueType = Some(f_))) def optionalValueType: _root_.scalapb.lenses.Lens[UpperPB, scala.Option[String]] = field(_.valueType)((c_, f_) => c_.copy(valueType = f_)) def annotations: _root_.scalapb.lenses.Lens[UpperPB, _root_.scala.collection.Seq[String]] = field(_.annotations)((c_, f_) => c_.copy(annotations = f_)) + def noBox: _root_.scalapb.lenses.Lens[UpperPB, Boolean] = field(_.getNoBox)((c_, f_) => c_.copy(noBox = Some(f_))) + def optionalNoBox: _root_.scalapb.lenses.Lens[UpperPB, scala.Option[Boolean]] = field(_.noBox)((c_, f_) => c_.copy(noBox = f_)) } final val TYPE_FIELD_NUMBER = 1 final val SCALA_NAME_FIELD_NUMBER = 2 @@ -197,4 +217,5 @@ object FieldOptions extends scalapb.GeneratedMessageCompanion[scalapb.options.Fi final val KEY_TYPE_FIELD_NUMBER = 4 final val VALUE_TYPE_FIELD_NUMBER = 5 final val ANNOTATIONS_FIELD_NUMBER = 6 + final val NO_BOX_FIELD_NUMBER = 30 } 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 dd06386b0..b92da2a27 100644 --- a/scalapb-runtime/shared/src/main/scala/scalapb/options/ScalapbProto.scala +++ b/scalapb-runtime/shared/src/main/scala/scalapb/options/ScalapbProto.scala @@ -28,19 +28,20 @@ object ScalapbProto extends _root_.scalapb.GeneratedFileObject { Hlfbm9famF2YV9jb252ZXJzaW9ucxihjQYgASgIUhl0ZXN0T25seU5vSmF2YUNvbnZlcnNpb25zIsIBCg5NZXNzYWdlT3B0aW9uc xIYCgdleHRlbmRzGAEgAygJUgdleHRlbmRzEisKEWNvbXBhbmlvbl9leHRlbmRzGAIgAygJUhBjb21wYW5pb25FeHRlbmRzEiAKC 2Fubm90YXRpb25zGAMgAygJUgthbm5vdGF0aW9ucxISCgR0eXBlGAQgASgJUgR0eXBlEjMKFWNvbXBhbmlvbl9hbm5vdGF0aW9uc - xgFIAMoCVIUY29tcGFuaW9uQW5ub3RhdGlvbnMixgEKDEZpZWxkT3B0aW9ucxISCgR0eXBlGAEgASgJUgR0eXBlEh0KCnNjYWxhX + xgFIAMoCVIUY29tcGFuaW9uQW5ub3RhdGlvbnMi3QEKDEZpZWxkT3B0aW9ucxISCgR0eXBlGAEgASgJUgR0eXBlEh0KCnNjYWxhX 25hbWUYAiABKAlSCXNjYWxhTmFtZRInCg9jb2xsZWN0aW9uX3R5cGUYAyABKAlSDmNvbGxlY3Rpb25UeXBlEhkKCGtleV90eXBlG AQgASgJUgdrZXlUeXBlEh0KCnZhbHVlX3R5cGUYBSABKAlSCXZhbHVlVHlwZRIgCgthbm5vdGF0aW9ucxgGIAMoCVILYW5ub3Rhd - GlvbnMiaAoLRW51bU9wdGlvbnMSGAoHZXh0ZW5kcxgBIAMoCVIHZXh0ZW5kcxIrChFjb21wYW5pb25fZXh0ZW5kcxgCIAMoCVIQY - 29tcGFuaW9uRXh0ZW5kcxISCgR0eXBlGAMgASgJUgR0eXBlIiwKEEVudW1WYWx1ZU9wdGlvbnMSGAoHZXh0ZW5kcxgBIAMoCVIHZ - Xh0ZW5kcyIoCgxPbmVvZk9wdGlvbnMSGAoHZXh0ZW5kcxgBIAMoCVIHZXh0ZW5kczpQCgdvcHRpb25zEhwuZ29vZ2xlLnByb3RvY - nVmLkZpbGVPcHRpb25zGPwHIAEoCzIXLnNjYWxhcGIuU2NhbGFQYk9wdGlvbnNSB29wdGlvbnM6UwoHbWVzc2FnZRIfLmdvb2dsZ - S5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxj8ByABKAsyFy5zY2FsYXBiLk1lc3NhZ2VPcHRpb25zUgdtZXNzYWdlOksKBWZpZWxkE - h0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxj8ByABKAsyFS5zY2FsYXBiLkZpZWxkT3B0aW9uc1IFZmllbGQ6VgoMZW51b - V9vcHRpb25zEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGPwHIAEoCzIULnNjYWxhcGIuRW51bU9wdGlvbnNSC2VudW1Pc - HRpb25zOlwKCmVudW1fdmFsdWUSIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucxj8ByABKAsyGS5zY2FsYXBiLkVud - W1WYWx1ZU9wdGlvbnNSCWVudW1WYWx1ZTpLCgVvbmVvZhIdLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMY/AcgASgLMhUuc - 2NhbGFwYi5PbmVvZk9wdGlvbnNSBW9uZW9mQicKD3NjYWxhcGIub3B0aW9uc+I/EwoPc2NhbGFwYi5vcHRpb25zEAE=""" + GlvbnMSFQoGbm9fYm94GB4gASgIUgVub0JveCJoCgtFbnVtT3B0aW9ucxIYCgdleHRlbmRzGAEgAygJUgdleHRlbmRzEisKEWNvb + XBhbmlvbl9leHRlbmRzGAIgAygJUhBjb21wYW5pb25FeHRlbmRzEhIKBHR5cGUYAyABKAlSBHR5cGUiLAoQRW51bVZhbHVlT3B0a + W9ucxIYCgdleHRlbmRzGAEgAygJUgdleHRlbmRzIigKDE9uZW9mT3B0aW9ucxIYCgdleHRlbmRzGAEgAygJUgdleHRlbmRzOlAKB + 29wdGlvbnMSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMY/AcgASgLMhcuc2NhbGFwYi5TY2FsYVBiT3B0aW9uc1IHb3B0a + W9uczpTCgdtZXNzYWdlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGPwHIAEoCzIXLnNjYWxhcGIuTWVzc2FnZU9wd + GlvbnNSB21lc3NhZ2U6SwoFZmllbGQSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGPwHIAEoCzIVLnNjYWxhcGIuRmllb + GRPcHRpb25zUgVmaWVsZDpWCgxlbnVtX29wdGlvbnMSHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMY/AcgASgLMhQuc2Nhb + GFwYi5FbnVtT3B0aW9uc1ILZW51bU9wdGlvbnM6XAoKZW51bV92YWx1ZRIhLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb + 25zGPwHIAEoCzIZLnNjYWxhcGIuRW51bVZhbHVlT3B0aW9uc1IJZW51bVZhbHVlOksKBW9uZW9mEh0uZ29vZ2xlLnByb3RvYnVmL + k9uZW9mT3B0aW9ucxj8ByABKAsyFS5zY2FsYXBiLk9uZW9mT3B0aW9uc1IFb25lb2ZCJwoPc2NhbGFwYi5vcHRpb25z4j8TCg9zY + 2FsYXBiLm9wdGlvbnMQAQ==""" ).mkString) lazy val scalaDescriptor: _root_.scalapb.descriptors.FileDescriptor = { val scalaProto = com.google.protobuf.descriptor.FileDescriptorProto.parseFrom(ProtoBytes)