From 5ea4622e9f0bb511a4fdd2b0ddf223213091da42 Mon Sep 17 00:00:00 2001 From: Andy Jewell Date: Mon, 4 Nov 2024 12:24:33 -0500 Subject: [PATCH] m --- .../generator/awssdk/v2/ToNativeAwsV2.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyjava/generator/awssdk/v2/ToNativeAwsV2.java b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyjava/generator/awssdk/v2/ToNativeAwsV2.java index e9efb9492..2a33b95d7 100644 --- a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyjava/generator/awssdk/v2/ToNativeAwsV2.java +++ b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyjava/generator/awssdk/v2/ToNativeAwsV2.java @@ -184,6 +184,7 @@ TypeSpec toNative() { .addMethods(convertServiceErrors) .addMethod(modeledService(subject.serviceShape)) .addMethod(errorOpaque()) + .addMethod(errorOpaqueWithText()) .addMethod(dafnyError()) .build(); } @@ -527,6 +528,59 @@ protected MethodSpec modeledUnion(final UnionShape shape) { } protected MethodSpec errorOpaque() { + final String methodName = "Error"; + final TypeName inputType = subject.dafnyNameResolver.classForOpaqueError(); + final ClassName returnType = ClassName.get(RuntimeException.class); + return initializeMethodSpec(methodName, inputType, returnType) + .addComment("While the first two cases are logically identical,") + .addComment("there is a semantic distinction.") + .addComment( + "An un-modeled Service Error is different from a Java Heap Exhaustion error." + ) + .addComment("In the future, Smithy-Dafny MAY allow for this distinction.") + .addComment( + "Which would allow Dafny developers to treat the two differently." + ) + // If obj is an instance of the Service's Base Exception + .beginControlFlow( + "if ($L.$L instanceof $T)", + VAR_INPUT, + Dafny.datatypeDeconstructor("obj"), + subject.nativeNameResolver.baseErrorForService() + ) + .addStatement( + "return ($T) $L.$L", + subject.nativeNameResolver.baseErrorForService(), + VAR_INPUT, + Dafny.datatypeDeconstructor("obj") + ) + // If obj is ANY Exception + .nextControlFlow( + "else if ($L.$L instanceof $T)", + VAR_INPUT, + Dafny.datatypeDeconstructor("obj"), + Exception.class + ) + .addStatement( + "return ($T) $L.$L", + RuntimeException.class, + VAR_INPUT, + Dafny.datatypeDeconstructor("obj") + ) + .endControlFlow() + // If obj is not ANY exception and String is not set, Give Up with IllegalStateException + .addStatement( + "return new $T(String.format($S, $L))", + IllegalStateException.class, + "Unknown error thrown while calling " + + AwsSdkNativeV2.titleForService(subject.serviceShape) + + ". %s", + VAR_INPUT + ) + .build(); + } + + protected MethodSpec errorOpaqueWithText() { final String methodName = "Error"; final TypeName inputType = subject.dafnyNameResolver.classForOpaqueWithTextError(); @@ -598,6 +652,7 @@ MethodSpec dafnyError() { .map(ClassName::simpleName) .map(simpleName -> simpleName.replaceFirst("Error_", "")) .collect(Collectors.toCollection(ArrayList::new)); // We need a mutable list, so we can't use stream().toList() + allDafnyErrorConstructors.add("Opaque"); allDafnyErrorConstructors.add("OpaqueWithText"); allDafnyErrorConstructors.forEach(constructorName -> method