smithy-translate
smithy-translate copied to clipboard
Crash when encountering an Operation with no output
Given this smithy:
$version: "2"
namespace test
use alloy.proto#protoEnabled
@protoEnabled
service Foo {
operations: [
BarNoOutput
]
}
operation BarNoOutput {
input := {
value: String
}
}
Running smithy translate to output protobuf fails like this:
smithytranslate smithy-to-proto --input ./smithy/foo.smithy ./out/proto
Exception in thread "main" java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.get(Optional.java:143)
at smithytranslate.proto3.internals.Compiler$rpcVisitor$.operationShape(Compiler.scala:514)
at smithytranslate.proto3.internals.Compiler$rpcVisitor$.operationShape(Compiler.scala:510)
at software.amazon.smithy.model.shapes.OperationShape.accept(OperationShape.java:76)
at smithytranslate.proto3.internals.Compiler$topLevelDefsVisitor$.$anonfun$serviceShape$3(Compiler.scala:254)
at scala.collection.immutable.List.flatMap(List.scala:294)
at smithytranslate.proto3.internals.Compiler$topLevelDefsVisitor$.serviceShape(Compiler.scala:254)
at smithytranslate.proto3.internals.Compiler$topLevelDefsVisitor$.serviceShape(Compiler.scala:215)
at software.amazon.smithy.model.shapes.ServiceShape.accept(ServiceShape.java:90)
at smithytranslate.proto3.internals.Compiler.$anonfun$compile$5(Compiler.scala:117)
at scala.collection.immutable.List.flatMap(List.scala:294)
at smithytranslate.proto3.internals.Compiler.$anonfun$compile$4(Compiler.scala:115)
at scala.collection.StrictOptimizedIterableOps.flatMap(StrictOptimizedIterableOps.scala:118)
at scala.collection.StrictOptimizedIterableOps.flatMap$(StrictOptimizedIterableOps.scala:105)
at scala.collection.immutable.HashMap.flatMap(HashMap.scala:39)
at smithytranslate.proto3.internals.Compiler.compile(Compiler.scala:114)
at smithytranslate.proto3.SmithyToProtoCompilerInterface.compile(SmithyToProtoCompiler.scala:34)
at smithytranslate.runners.Proto$.run(Proto.scala:78)
at smithytranslate.runners.Proto$.runProto(Proto.scala:61)
at smithytranslate.cli.Main$$anonfun$$lessinit$greater$1.apply(Main.scala:80)
at smithytranslate.cli.Main$$anonfun$$lessinit$greater$1.apply(Main.scala:49)
at scala.Function1.$anonfun$andThen$1(Function1.scala:87)
at scala.Function1.$anonfun$andThen$1(Function1.scala:87)
at cats.data.Validated.andThen(Validated.scala:727)
at com.monovore.decline.Parser$Accumulator$Validate.$anonfun$mapValidated$1(Parser.scala:413)
at scala.Function1.$anonfun$andThen$1(Function1.scala:87)
at cats.data.Validated.andThen(Validated.scala:727)
at com.monovore.decline.Result.$anonfun$mapValidated$2(Result.scala:13)
at cats.instances.Function0Instances$$anon$4.$anonfun$map$1(function.scala:100)
at com.monovore.decline.Parser.evalResult(Parser.scala:30)
at com.monovore.decline.Parser.$anonfun$consumeAll$3(Parser.scala:107)
at scala.util.Either.flatMap(Either.scala:360)
at com.monovore.decline.Parser.$anonfun$consumeAll$1(Parser.scala:107)
at scala.Option.map(Option.scala:242)
at com.monovore.decline.Parser.consumeAll(Parser.scala:106)
at com.monovore.decline.Parser.apply(Parser.scala:19)
at com.monovore.decline.Command.parse(opts.scala:20)
at smithytranslate.cli.CommandApp.main(CommandApp.scala:81)
at smithytranslate.cli.Main.main(Main.scala)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at coursier.bootstrap.launcher.a.a(Unknown Source)
at coursier.bootstrap.launcher.Launcher.main(Unknown Source)
This fails validation if I add @grpc trait to the service, which gives the clue: the service must have an output.
Expected: validation error (or even better: assume Unit for output type)
I don't recall the reason for preventing operations without an output (for reference, operations with no output are equivalent to Unit output in Smithy, in other words Unit is implied if no explicit type is provided).
It seems like we could use something like: https://protobuf.dev/reference/protobuf/google.protobuf/#empty