Skip to content

Commit

Permalink
Add an option not to wrap some values in Options when generating Scal…
Browse files Browse the repository at this point in the history
…a values (#383)

Add an option not to wrap some values in Options when generating Scala values

Fixes #40
  • Loading branch information
Fabian Gebert authored and thesamet committed Jan 7, 2018
1 parent ae9fcc5 commit 92bb35f
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 56 deletions.
160 changes: 140 additions & 20 deletions compiler-plugin/src/main/java/scalapb/options/compiler/Scalapb.java

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
}
}
14 changes: 14 additions & 0 deletions e2e/src/main/protobuf/no_box.proto
Original file line number Diff line number Diff line change
@@ -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];
}
39 changes: 39 additions & 0 deletions e2e/src/test/scala/NoBoxSpec.scala
Original file line number Diff line number Diff line change
@@ -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)
}
}
3 changes: 3 additions & 0 deletions protobuf/scalapb/scalapb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 92bb35f

Please sign in to comment.