@@ -4,11 +4,173 @@ This library supports the standard Smithy workflow
4
4
for generating a Dafny client for a given Smithy model,
5
5
as described in the
6
6
[ Smithy codegen docs] ( https://smithy.io/2.0/guides/using-code-generation/generating-a-client.html ) .
7
- For now the library will only support AWS service models,
7
+
8
+ * WARNING: All internal and external interfaces are considered unstable and subject to change without notice.
9
+ This includes the interfaces in the code generated by this library.*
10
+
11
+ ## Limitations
12
+
13
+ 1 . Dafny supports compilation to multiple other target programming languages,
14
+ but of those targets, this plugin currently only supports .NET.
15
+ Experimental support for Java exists
16
+ but does not yet work for arbitrary service models.
17
+ 2 . This plugin does not yet handle all Smithy features,
18
+ and may hit errors or generate incorrect code for some models.
19
+ See the section below on "Using projections" for details
20
+ on how to cleanly avoid unsupported features.
21
+
22
+ ## Generating a client
23
+
24
+ This repository builds Dafny declarations and Dafny clients from Smithy
25
+ models.
26
+
27
+ For now the library only supports AWS service models,
8
28
since the implementation will generate both Dafny code and target language code
9
29
to wrap existing AWS SDKs.
30
+ This means only services with the ` aws.api#service ` trait are supported.
31
+
32
+ The ` TestModel/sqs ` package in this repo is an example of
33
+ how to build a Dafny client. The steps needed to build a Dafny client
34
+ are as follows:
35
+
36
+ 1 . Create a new directory for your package. For example, "foo-client".
37
+
38
+ 2 . Create a ` build.gradle.kts ` file with the following contents:
39
+
40
+ ``` kotlin
41
+ buildscript {
42
+ repositories {
43
+ mavenCentral()
44
+ }
45
+ dependencies {
46
+ " classpath" (" software.amazon.smithy:smithy-cli:1.28.1" )
47
+ }
48
+ }
49
+
50
+ plugins {
51
+ id(" software.amazon.smithy" ).version(" 0.6.0" )
52
+ }
53
+
54
+ repositories {
55
+ mavenLocal()
56
+ mavenCentral()
57
+ }
58
+
59
+ dependencies {
60
+ implementation(" software.amazon.smithy:smithy-model:1.28.1" )
61
+ implementation(" software.amazon.smithy:smithy-aws-traits:1.28.1" )
62
+ implementation(" software.amazon.smithy.dafny:smithy-dafny-codegen:0.1.0" )
63
+ }
64
+ ```
65
+
66
+ You may need additional Smithy dependencies depending on what Smithy features
67
+ your service model depends on, such as AWS-specific traits.
68
+ See https://smithy.io/2.0/guides/using-code-generation/index.html for more examples.
69
+
70
+ Note the exact version of the ` software.amazon.smithy ` dependencies MAY NOT need to be
71
+ ` 1.28.1 ` exactly, but MUST be consistent.
72
+
73
+ 3 . Clone the GitHub repository for [ smithy-dafny] ( https://github.com/awslabs/smithy-dafny )
74
+ somewhere nearby, being sure to initialize submodules.
75
+ If this repository is still private, reach out to
[email protected]
76
+ for access.
77
+
78
+ This is necessary because it contains reusable Dafny code that
79
+ the generated client will depend on, but is not yet independently distributed for
80
+ shared use.
81
+
82
+ 4 . Create a ` smithy-build.json ` file with the following contents,
83
+ substituting "smithy.example#ExampleService" with the name of the service
84
+ to generate a client for, and specifying the set of target languages
85
+ to support in the generated client:
86
+
87
+ ``` json
88
+ {
89
+ "version" : " 1.0" ,
90
+ "plugins" : {
91
+ "dafny-client-codegen" : {
92
+ "edition" : " 2023" ,
93
+ "service" : " smithy.example#ExampleService" ,
94
+ "targetLanguages" : [" dotnet" ],
95
+ "includeDafnyPath" : " [relative]/[path]/[to]/smithy-dafny/TestModels/dafny-dependencies/StandardLibrary/src/Index.dfy"
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ See [ ` DafnyClientCodegenPluginSettings.java ` ] ( https://github.com/awslabs/smithy-dafny/blob/main-1.x/codegen/smithy-dafny-codegen/src/main/java/software/amazon/smithy/dafny/codegen/DafnyClientCodegenPluginSettings.java ) for more details about plugin settings.
102
+
103
+ 5 . Create a directory named ` model ` . This is where all of your Smithy models
104
+ will go.
105
+
106
+ 6 . Copy the model for the service into the ` model ` directory.
107
+ The Smithy models for AWS services can be found in several Smithy-based SDK projects,
108
+ such as
109
+ https://github.com/aws/aws-sdk-js-v3/tree/main/codegen/sdk-codegen/aws-models .
110
+
111
+ 7 . Run ` gradle build ` (alternatively, you can use a
112
+ [ Gradle wrapper] ( https://docs.gradle.org/current/userguide/gradle_wrapper.html ) ).
113
+
114
+ 8 . The generated client can be found in ` build/smithyprojections/foo-client/source/dafny-client-codegen ` .
115
+
116
+ See [ the Smithy documentation] ( https://smithy.io/2.0/guides/building-models/gradle-plugin.html )
117
+ for more information on building Smithy projects with Gradle.
118
+
119
+ Note there are some caveats related to building the generated client code:
120
+
121
+ 1 . If you specified Java as a target language,
122
+ the result will depend on the [ dafny-java-conversion] ( https://github.com/awslabs/smithy-dafny/tree/main-1.x/dafny-java-conversion )
123
+ library, which is also not yet published.
124
+ The easiest workaround is to first run the ` publishToLocalMaven ` gradle task on a copy of the source for that library.
125
+
126
+ ## Using projections
127
+
128
+ This plugin does not yet handle all Smithy features, especially since
129
+ at the time of writing this, Dafny itself does not have a strongly
130
+ idiomatic representation for concepts such as Timestamps.
131
+ Fortunately, the Smithy Gradle plugin provides several
132
+ [ "transforms"] ( https://smithy.io/2.0/guides/building-models/build-config.html#transforms )
133
+ that can be used to filter a service model
134
+ to remove unsupported shapes.
135
+
136
+ The following example removes all operations that transitively refer
137
+ to some of the shape types that this plugin does not yet support:
138
+
139
+ ``` json
140
+ {
141
+ "version" : " 1.0" ,
142
+ "projections" : {
143
+ "dafny-supported" : {
144
+ "transforms" : [
145
+ {
146
+ "name" : " excludeShapesBySelector" ,
147
+ "args" : {
148
+ "selector" : " operation :test(~> timestamp, double, float, resource)"
149
+ }
150
+ }
151
+ ],
152
+ "plugins" : {
153
+ "dafny-client-codegen" : {
154
+ "service" : " smithy.example#ExampleService" ,
155
+ "targetLanguages" : [" dotnet" ],
156
+ "includeDafnyPath" : " [relative]/[path]/[to]/smithy-dafny/TestModels/dafny-dependencies/StandardLibrary/src/Index.dfy"
157
+ }
158
+ }
159
+ }
160
+ },
161
+ }
162
+ ```
163
+
164
+ Note that if you are using transformations to avoid unsupported features,
165
+ the plugin has to be applied specifically to projections that use such transformations,
166
+ and not at the top level were it will be applied to all projections.
167
+ Otherwise the built-in "source" projection will still hit errors.
168
+
169
+ Refer to the Smithy documentation for more information about other transforms
170
+ that might be useful, but bear in mind that removing arbitrary shapes may lead
171
+ to a client that will fail to compile or not function correctly.
10
172
11
- * WARNING: All internal and external interfaces are considered unstable and subject to change without notice. *
173
+ ## Development
12
174
13
175
The file layout of the library follows the
14
176
[ Codegen repo layout] ( https://smithy.io/2.0/guides/building-codegen/creating-codegen-repo.html#codegen-repo-layout )
0 commit comments