Skip to content

Commit 4787373

Browse files
texastonyseebeeslucasmcdonald3
authored
fix(Java): un-wrap extended resources (#215)
Co-authored-by: seebees <ryanemer@amazon.com> Co-authored-by: Lucas McDonald <lucasmcdonald3@gmail.com>
1 parent 790bd4c commit 4787373

File tree

7 files changed

+76
-31
lines changed

7 files changed

+76
-31
lines changed

Diff for: TestModels/Extendable/Makefile

+11
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,14 @@ NAMESPACE=simple.extendable.resources
1313

1414
format_net:
1515
pushd runtimes/net && dotnet format && popd
16+
17+
clean:
18+
rm -f $(LIBRARY_ROOT)/Model/*Types.dfy $(LIBRARY_ROOT)/Model/*TypesWrapped.dfy
19+
rm -f $(LIBRARY_ROOT)/runtimes/net/ImplementationFromDafny.cs
20+
rm -f $(LIBRARY_ROOT)/runtimes/net/tests/TestFromDafny.cs
21+
rm -rf $(LIBRARY_ROOT)/TestResults
22+
rm -rf $(LIBRARY_ROOT)/runtimes/net/Generated $(LIBRARY_ROOT)/runtimes/net/bin $(LIBRARY_ROOT)/runtimes/net/obj
23+
rm -rf $(LIBRARY_ROOT)/runtimes/net/tests/bin $(LIBRARY_ROOT)/runtimes/net/tests/obj
24+
rm -rf $(LIBRARY_ROOT)/runtimes/java/src/main/dafny-generated
25+
rm -rf $(LIBRARY_ROOT)/runtimes/java/src/main/smithy-generated
26+
rm -rf $(LIBRARY_ROOT)/runtimes/java/src/test/dafny-generated

Diff for: TestModels/Extendable/runtimes/java/src/test/java/Dafny/Simple/Extendable/Resources/Wrapped/__default.java

+20
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,37 @@
44
import simple.extendable.resources.ToNative;
55
import simple.extendable.resources.wrapped.TestSimpleExtendableResources;
66

7+
import Dafny.Simple.Extendable.Resources.Types.IExtendableResource;
78
import Dafny.Simple.Extendable.Resources.Types.ISimpleExtendableResourcesClient;
89
import Dafny.Simple.Extendable.Resources.Types.Error;
910

1011
import Dafny.Simple.Extendable.Resources.Types.SimpleExtendableResourcesConfig;
12+
import Simple.Extendable.Resources.NativeResource;
1113
import Wrappers_Compile.Result;
1214

15+
import static Dafny.Simple.Extendable.Resources.NativeResourceFactory.__default.DafnyFactory;
16+
1317
public class __default extends _ExternBase___default {
1418
public static Result<ISimpleExtendableResourcesClient, Error> WrappedSimpleExtendableResources(SimpleExtendableResourcesConfig config) {
19+
TestUnwrapExtendable();
1520
simple.extendable.resources.model.SimpleExtendableResourcesConfig wrappedConfig = ToNative.SimpleExtendableResourcesConfig(config);
1621
simple.extendable.resources.SimpleExtendableResources impl = SimpleExtendableResources.builder().SimpleExtendableResourcesConfig(wrappedConfig).build();
1722
TestSimpleExtendableResources wrappedClient = TestSimpleExtendableResources.builder().impl(impl).build();
1823
return Result.create_Success(wrappedClient);
1924
}
25+
26+
/**
27+
* We have not developed the ability to call ToNative from Dafny source code at this time.
28+
* But we need to test this un-wrapping, so this is written in native code until we figure that out.
29+
*/
30+
public static void TestUnwrapExtendable() {
31+
IExtendableResource dafnyWrappingNativeWrappingDafny = DafnyFactory();
32+
simple.extendable.resources.IExtendableResource nativeWrappingDafny = ToNative.ExtendableResource(dafnyWrappingNativeWrappingDafny);
33+
if (!(nativeWrappingDafny instanceof NativeResource)) {
34+
throw new AssertionError(
35+
"Polymorph MUST generate conversion methods " +
36+
"capable of wrapping & un-wrapping" +
37+
"these native resources.");
38+
}
39+
}
2040
}

Diff for: TestModels/dafny-dependencies/Model/traits.smithy

+7-19
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,13 @@ structure dafnyUtf8Bytes {}
5353

5454
// A trait indicating that the resource may be implemented by native code (instead of Dafny code).
5555
// i.e.: Users may author their own classes that implement and extend this resource.
56-
// Polymorph will generate and utilize NativeWrappers for these resources.
56+
// Polymorph MUST generate and utilize NativeWrappers for these resources.
57+
// Polymorph MUST generate conversion methods capabale of wrapping & un-wrapping
58+
// these native resources.
59+
// i.e.: The wrapping MUST NOT be a one way door.
5760
@trait(selector: "resource")
5861
structure extendable {}
5962

60-
// A trait indicating that a structure is a members of a union
61-
// and MUST NOT be used independently of the union.
62-
// This is syntactic sugar for
63-
// union Foo {
64-
// Bar: structure Bar { baz: String }
65-
// }
66-
//
67-
// It is used like this
68-
// union Foo {
69-
// Bar: Bar
70-
// }
71-
// structure Bar { baz: String }
72-
// This is especilay useful in Dafny.
73-
// Because it results in a single datatype
74-
// whos constructors are the member structures.
75-
// datatypes Foo = Bar( baz: String )
76-
@trait(selector: "structure")
77-
structure datatypeUnion {}
63+
// A trait to indicate that a resource stores local state
64+
@trait(selector: "resource")
65+
structure mutableLocalState {}

Diff for: TestModels/dafny-dependencies/Model/update.sh

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Example: ./update.sh ~/workplace/private-aws-encryption-sdk-dafny-staging v4-seperate-modules
44
ESDK_PATH="$1"
55
ESDK_BRANCH="$2"
6-
MDL_SRC_DIRS=('aws-sdk')
6+
MDL_SRC_FILES=('traits.smithy')
77

88
set -e
99

@@ -12,13 +12,16 @@ if [ "$2" ]; then
1212
git checkout "$ESDK_BRANCH"
1313
git pull
1414
fi
15+
1516
ESDK_COMMIT_SHA=$(git rev-parse --short HEAD)
1617
echo -e "ESDK Commit Sha is $ESDK_COMMIT_SHA"
1718
cd -
18-
for DIRECTORY in "${MDL_SRC_DIRS[@]}"; do
19-
cp -r "$ESDK_PATH/model/$DIRECTORY" "."
20-
git add "$DIRECTORY"
19+
20+
for MDL_FILE in "${MDL_SRC_FILES[@]}"; do
21+
cp "$ESDK_PATH/model/$MDL_FILE" "."
22+
git add "$MDL_FILE"
2123
done
24+
2225
printf "Pulled Files for ESDK's model and staged for commit. \n"
2326
printf "Suggest executing: \n"
2427
COMMIT_MSG="chore(tests): Update ESDK's Model to $ESDK_COMMIT_SHA"

Diff for: codegen/gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
smithyVersion=1.28.1
22
smithyGradleVersion=0.6.0
3+
org.gradle.warning.mode=none

Diff for: codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyjava/generator/library/ToNativeLibrary.java

+23-5
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import software.amazon.polymorph.traits.PositionalTrait;
2222
import software.amazon.polymorph.utils.ModelUtils;
2323
import software.amazon.polymorph.smithyjava.nameresolver.Dafny;
24+
import software.amazon.polymorph.smithyjava.nameresolver.Native;
2425
import software.amazon.polymorph.smithyjava.unmodeled.CollectionOfErrors;
2526
import software.amazon.polymorph.smithyjava.unmodeled.NativeError;
2627
import software.amazon.polymorph.smithyjava.unmodeled.OpaqueError;
28+
import software.amazon.polymorph.traits.ExtendableTrait;
2729

2830
import software.amazon.smithy.model.shapes.MemberShape;
2931
import software.amazon.smithy.model.shapes.ResourceShape;
@@ -201,14 +203,30 @@ protected MethodSpec positionalStructure(StructureShape structureShape) {
201203

202204
protected MethodSpec modeledResource(ResourceShape shape) {
203205
final String methodName = capitalize(shape.getId().getName());
204-
return MethodSpec
206+
MethodSpec.Builder method = MethodSpec
205207
.methodBuilder(methodName)
206208
.addModifiers(PUBLIC_STATIC)
207209
.addParameter(Dafny.interfaceForResource(shape), VAR_INPUT)
208-
.returns(subject.nativeNameResolver.classNameForResource(shape))
209-
.addStatement("return $L", subject.wrapWithShim(shape.getId(),
210-
CodeBlock.of(VAR_INPUT)))
211-
.build();
210+
.returns(Native.classNameForInterfaceOrLocalService(shape, subject.sdkVersion));
211+
212+
if (shape.hasTrait(ExtendableTrait.class)) {
213+
method
214+
.beginControlFlow(
215+
"if ($L instanceof $T.NativeWrapper)",
216+
VAR_INPUT, subject.nativeNameResolver.classNameForResource(shape)
217+
)
218+
.addStatement(
219+
"return (($T.NativeWrapper) $L)._impl",
220+
subject.nativeNameResolver.classNameForResource(shape), VAR_INPUT
221+
)
222+
.endControlFlow();
223+
}
224+
return method
225+
.addStatement(
226+
"return $L",
227+
subject.wrapWithShim(shape.getId(), CodeBlock.of(VAR_INPUT))
228+
)
229+
.build();
212230
}
213231

214232
protected CodeBlock returnWithConversionCall(final MemberShape shape) {

Diff for: codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyjava/generator/library/shims/NativeWrapper.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import software.amazon.smithy.model.shapes.ResourceShape;
1616

1717
import static javax.lang.model.element.Modifier.FINAL;
18-
import static javax.lang.model.element.Modifier.PRIVATE;
18+
import static javax.lang.model.element.Modifier.PROTECTED;
1919
import static javax.lang.model.element.Modifier.STATIC;
2020

2121
public class NativeWrapper extends ResourceShim {
@@ -37,9 +37,13 @@ TypeSpec nativeWrapper() {
3737
ClassName className = className();
3838
TypeSpec.Builder spec =TypeSpec
3939
.classBuilder(className)
40-
.addModifiers(PRIVATE, FINAL, STATIC)
40+
// TODO: Verify that the nested class SHOULD BE `PROTECTED` instead of `PRIVATE`
41+
// PR #215 or #196
42+
.addModifiers(PROTECTED, FINAL, STATIC)
4143
.addSuperinterface(Dafny.interfaceForResource(targetShape))
42-
.addField(interfaceName, INTERFACE_FIELD, PRIVATE, FINAL)
44+
// TODO: It MAYBE best to keep the INTERFACE_FIELD PRIVATE, rather than PROTECTED,
45+
// and add getter method. PR #215 or #196
46+
.addField(interfaceName, INTERFACE_FIELD, PROTECTED, FINAL)
4347
.addMethod(nativeWrapperConstructor());
4448
getOperationsForTarget().forEach(oShape -> {
4549
spec.addMethod(operation(oShape));

0 commit comments

Comments
 (0)