Skip to content

Commit

Permalink
Disallow typemapping sealed oneof cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
thesamet committed Apr 23, 2021
1 parent 4d52ee7 commit 76660b2
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ class ProtoValidation(implicits: DescriptorImplicits) {
s"${m.getFullName}.${field.getName}: all sealed oneof cases must be defined in the same file as the sealed oneof field."
)
}
fields.find(_.customSingleScalaTypeName.isDefined).foreach { field =>
throw new GeneratorException(
s"${m.getFullName}.${field.getName}: sealed oneof cases may not have custom types."
)
}
val distinctTypes = fields.map(_.getMessageType).toSet
if (distinctTypes.size != fields.size) {
throw new GeneratorException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,24 @@ class ProtoValidationSpec extends AnyFlatSpec with Matchers with ProtocInvocatio
}.message must include("Sealed oneofs can not be type mapped. Use regular oneofs instead.")
}

it should "fail when a sealed oneof case is typemapped" in {
intercept[GeneratorException] {
runValidation(
"file.proto" ->
"""
|syntax = "proto2";
|import "scalapb/scalapb.proto";
|message Case1 {}
|message MyOneof {
| oneof sealed_value {
| Case1 case1 = 1 [(scalapb.field).type="SomeType"];
| }
|}
""".stripMargin
)
}.message must include("sealed oneof cases may not have custom types.")
}

it should "fail when sealed_oneof_extends used outside of a sealed oneof type" in {
intercept[GeneratorException] {
runValidation(
Expand Down
3 changes: 3 additions & 0 deletions docs/src/main/markdown/sealed-oneofs.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ A sealed oneof is detected when a message (denoted below as the *containing mess

6. A message type can appear in at most one sealed oneof.

7. Sealed oneofs and the fields within them can not be typemapped to custom
types.

## Experimental Status

Some of the rules above are inherently required (for example, that the message types need to be distinct). Other rules, such as the one requesting that all involved messages need to be inside the same namespace, were added to make the implementation simpler. That particular rule helps ensuring that all the cases can be generated into a single Scala source file without changing too much the existing way the code generator works. It is possible that some of the rules will change over time, though most likely they are only going to become less restrictive so existing code does not break.
Expand Down

0 comments on commit 76660b2

Please sign in to comment.