15
15
16
16
package software .amazon .smithy .aws .typescript .codegen ;
17
17
18
- import java .util .List ;
19
- import java .util .Map ;
20
- import java .util .TreeMap ;
21
- import software .amazon .smithy .codegen .core .Symbol ;
22
- import software .amazon .smithy .codegen .core .SymbolProvider ;
23
- import software .amazon .smithy .model .knowledge .HttpBinding ;
24
- import software .amazon .smithy .model .knowledge .HttpBinding .Location ;
25
- import software .amazon .smithy .model .shapes .CollectionShape ;
26
- import software .amazon .smithy .model .shapes .MapShape ;
27
- import software .amazon .smithy .model .shapes .MemberShape ;
28
- import software .amazon .smithy .model .shapes .OperationShape ;
29
- import software .amazon .smithy .model .shapes .Shape ;
30
- import software .amazon .smithy .model .shapes .ShapeId ;
31
- import software .amazon .smithy .model .shapes .ShapeIndex ;
32
- import software .amazon .smithy .model .shapes .StructureShape ;
33
- import software .amazon .smithy .model .shapes .UnionShape ;
34
- import software .amazon .smithy .model .traits .JsonNameTrait ;
35
- import software .amazon .smithy .model .traits .TimestampFormatTrait .Format ;
36
- import software .amazon .smithy .typescript .codegen .TypeScriptWriter ;
37
- import software .amazon .smithy .typescript .codegen .integration .HttpBindingProtocolGenerator ;
38
- import software .amazon .smithy .typescript .codegen .integration .ProtocolGenerator ;
39
-
40
- public class AwsRestJson1_1 extends HttpBindingProtocolGenerator {
18
+ /**
19
+ * Handles generating the aws.rest-json-1.1 protocol for services.
20
+ *
21
+ * @inheritDoc
22
+ *
23
+ * @see RestJsonDocumentBodyGenerator
24
+ */
25
+ public final class AwsRestJson1_1 extends RestJsonDocumentBodyGenerator {
41
26
42
27
@ Override
43
28
public String getName () {
@@ -48,293 +33,4 @@ public String getName() {
48
33
protected String getDocumentContentType () {
49
34
return "application/x-amz-json-1.1" ;
50
35
}
51
-
52
- @ Override
53
- protected Format getDocumentTimestampFormat () {
54
- return Format .EPOCH_SECONDS ;
55
- }
56
-
57
- @ Override
58
- public void generateSharedComponents (GenerationContext context ) {
59
- super .generateSharedComponents (context );
60
-
61
- TypeScriptWriter writer = context .getWriter ();
62
-
63
- writer .addImport ("SerdeContext" , "SerdeContext" , "@aws-sdk/types" );
64
- writer .openBlock ("const parseBody = (streamBody: any, context: SerdeContext): any => {" , "};" ,
65
- () -> {
66
- writer .openBlock ("return context.streamCollector(streamBody).then((body: any) => {" , "});" , () -> {
67
- writer .write ("return JSON.parse(context.utf8Encoder(body));" );
68
- });
69
- });
70
-
71
- writer .write ("" );
72
- }
73
-
74
- @ Override
75
- protected void serializeDocument (
76
- GenerationContext context ,
77
- OperationShape operation ,
78
- List <HttpBinding > documentBindings
79
- ) {
80
- SymbolProvider symbolProvider = context .getSymbolProvider ();
81
- TypeScriptWriter writer = context .getWriter ();
82
-
83
- writer .write ("let bodyParams: any = {};" );
84
- for (HttpBinding binding : documentBindings ) {
85
- // The name of the member to get from the input shape.
86
- String memberName = symbolProvider .toMemberName (binding .getMember ());
87
- // Use the jsonName trait value if present, otherwise use the member name.
88
- String locationName = binding .getMember ().getTrait (JsonNameTrait .class )
89
- .map (JsonNameTrait ::getValue )
90
- .orElseGet (binding ::getLocationName );
91
- writeDocumentStructureMemberSerialization (context , memberName , locationName , binding .getMember ());
92
- }
93
-
94
- writer .write ("body = JSON.stringify(bodyParams);" );
95
- }
96
-
97
- @ Override
98
- protected void serializeDocumentStructure (GenerationContext context , StructureShape shape ) {
99
- TypeScriptWriter writer = context .getWriter ();
100
-
101
- writer .write ("let bodyParams: any = {};" );
102
- // Use a TreeMap to sort the members.
103
- Map <String , MemberShape > members = new TreeMap <>(shape .getAllMembers ());
104
- members .forEach ((memberName , memberShape ) -> {
105
- // Use the jsonName trait value if present, otherwise use the member name.
106
- String locationName = memberShape .getTrait (JsonNameTrait .class )
107
- .map (JsonNameTrait ::getValue )
108
- .orElse (memberName );
109
- writeDocumentStructureMemberSerialization (context , memberName , locationName , memberShape );
110
- });
111
- writer .write ("return bodyParams;" );
112
- }
113
-
114
- private void writeDocumentStructureMemberSerialization (
115
- GenerationContext context ,
116
- String memberName ,
117
- String locationName ,
118
- MemberShape member
119
- ) {
120
- TypeScriptWriter writer = context .getWriter ();
121
- Shape target = context .getModel ().getShapeIndex ().getShape (member .getTarget ()).get ();
122
-
123
- // Generate an if statement to set the bodyParam if the member is set.
124
- writer .openBlock ("if (input.$L !== undefined) {" , "}" , memberName , () -> {
125
- writer .write ("bodyParams['$L'] = $L;" , locationName ,
126
- // Dispatch to the input value provider for any additional handling.
127
- getInputValue (context , Location .DOCUMENT , "input." + memberName , member , target ));
128
- });
129
- }
130
-
131
- @ Override
132
- protected void serializeDocumentCollection (GenerationContext context , CollectionShape shape ) {
133
- TypeScriptWriter writer = context .getWriter ();
134
- Shape target = context .getModel ().getShapeIndex ().getShape (shape .getMember ().getTarget ()).get ();
135
-
136
- // Dispatch to the input value provider for any additional handling.
137
- writer .openBlock ("return (input || []).map(entry =>" , ");" , () -> {
138
- writer .write (getInputValue (context , Location .DOCUMENT , "entry" , shape .getMember (), target ));
139
- });
140
- }
141
-
142
- @ Override
143
- protected void serializeDocumentMap (GenerationContext context , MapShape shape ) {
144
- TypeScriptWriter writer = context .getWriter ();
145
- Shape target = context .getModel ().getShapeIndex ().getShape (shape .getValue ().getTarget ()).get ();
146
-
147
- // Get the right serialization for each entry in the map. Undefined
148
- // inputs won't have this serializer invoked.
149
- writer .write ("let mapParams: any = {};" );
150
- writer .openBlock ("Object.keys(input).forEach(key => {" , "});" , () -> {
151
- writer .write ("mapParams[key] = $L;" ,
152
- // Dispatch to the input value provider for any additional handling.
153
- getInputValue (context , Location .DOCUMENT , "input[key]" , shape .getValue (), target ));
154
- });
155
- writer .write ("return mapParams;" );
156
- }
157
-
158
- @ Override
159
- protected void serializeDocumentUnion (GenerationContext context , UnionShape shape ) {
160
- TypeScriptWriter writer = context .getWriter ();
161
- ShapeIndex index = context .getModel ().getShapeIndex ();
162
-
163
- // Visit over the union type, then get the right serialization for the member.
164
- writer .openBlock ("return $L.visit(input, {" , "});" , shape .getId ().getName (), () -> {
165
- // Use a TreeMap to sort the members.
166
- Map <String , MemberShape > members = new TreeMap <>(shape .getAllMembers ());
167
- members .forEach ((memberName , memberShape ) -> {
168
- Shape target = index .getShape (memberShape .getTarget ()).get ();
169
- // Dispatch to the input value provider for any additional handling.
170
- writer .write ("$L: value => $L," , memberName ,
171
- getInputValue (context , Location .DOCUMENT , "value" , memberShape , target ));
172
- });
173
- writer .write ("_: value => value" );
174
- });
175
- }
176
-
177
- @ Override
178
- protected void deserializeDocument (
179
- GenerationContext context ,
180
- OperationShape operation ,
181
- List <HttpBinding > documentBindings
182
- ) {
183
- TypeScriptWriter writer = context .getWriter ();
184
- SymbolProvider symbolProvider = context .getSymbolProvider ();
185
-
186
- for (HttpBinding binding : documentBindings ) {
187
- Shape target = context .getModel ().getShapeIndex ().getShape (binding .getMember ().getTarget ()).get ();
188
- // The name of the member to get from the input shape.
189
- String memberName = symbolProvider .toMemberName (binding .getMember ());
190
- // Use the jsonName trait value if present, otherwise use the member name.
191
- String locationName = binding .getMember ().getTrait (JsonNameTrait .class )
192
- .map (JsonNameTrait ::getValue )
193
- .orElseGet (binding ::getLocationName );
194
- writer .openBlock ("if (data.$L !== undefined) {" , "}" , locationName , () -> {
195
- writer .write ("contents.$L = $L;" , memberName ,
196
- // Dispatch to the output value provider for any additional handling.
197
- getOutputValue (context , Location .DOCUMENT , "data." + locationName ,
198
- binding .getMember (), target ));
199
- });
200
- }
201
- }
202
-
203
- @ Override
204
- protected void writeErrorDeserializationDispatcher (
205
- GenerationContext context ,
206
- List <ShapeId > errors ,
207
- String unknownErrorNamespace
208
- ) {
209
- TypeScriptWriter writer = context .getWriter ();
210
- SymbolProvider symbolProvider = context .getSymbolProvider ();
211
-
212
- writer .write ("let errorCode: String = output.headers[\" x-amzn-errortype\" ].split(':')[0];" );
213
- writer .openBlock ("switch (errorCode) {" , "}" , () -> {
214
- // Generate the case statement for each error, invoking the specific deserializer.
215
- errors .forEach (errorId -> {
216
- Shape error = context .getModel ().getShapeIndex ().getShape (errorId ).get ();
217
- Symbol symbol = symbolProvider .toSymbol (error );
218
- String methodName = ProtocolGenerator .getDeserFunctionName (symbol , getName ());
219
- writer .openBlock ("case $S:\n case $S:" , " break;" , errorId .getName (), errorId .toString (), () -> {
220
- // Dispatch to the error deserialization function.
221
- writer .write ("response = $L(data, context);" , methodName );
222
- });
223
- });
224
-
225
- // Build a generic error the best we can for ones we don't know about.
226
- writer .openBlock ("default:" , "" , () -> {
227
- writer .write ("errorCode = errorCode || \" UnknownError\" ;" );
228
- writer .openBlock ("response = {" , "};" , () -> {
229
- writer .write ("__type: `$L#$${errorCode}`," , unknownErrorNamespace );
230
- writer .write ("$$name: errorCode," );
231
- writer .write ("$$fault: \" client\" ," );
232
- });
233
- });
234
- });
235
- }
236
-
237
- @ Override
238
- protected void deserializeError (GenerationContext context , StructureShape shape ) {
239
- // Use a TreeMap to sort the members.
240
- Map <String , MemberShape > members = new TreeMap <>(shape .getAllMembers ());
241
- members .forEach ((memberName , memberShape ) -> {
242
- // Use the jsonName trait value if present, otherwise use the member name.
243
- String locationName = memberShape .getTrait (JsonNameTrait .class )
244
- .map (JsonNameTrait ::getValue )
245
- .orElse (memberName );
246
- writeDocumentStructureMemberDeserialization (context , memberName , locationName , memberShape );
247
- });
248
- }
249
-
250
- @ Override
251
- protected void deserializeDocumentStructure (GenerationContext context , StructureShape shape ) {
252
- TypeScriptWriter writer = context .getWriter ();
253
-
254
- // Prepare the document contents structure.
255
- writer .openBlock ("let contents: any = {" , "};" , () -> {
256
- writer .write ("$$namespace: $S," , shape .getId ().getNamespace ());
257
- writer .write ("$$name: $S" , shape .getId ().getName ());
258
- });
259
- // Use a TreeMap to sort the members.
260
- Map <String , MemberShape > members = new TreeMap <>(shape .getAllMembers ());
261
- members .forEach ((memberName , memberShape ) -> {
262
- // Use the jsonName trait value if present, otherwise use the member name.
263
- String locationName = memberShape .getTrait (JsonNameTrait .class )
264
- .map (JsonNameTrait ::getValue )
265
- .orElse (memberName );
266
- writeDocumentStructureMemberDeserialization (context , memberName , locationName , memberShape );
267
- });
268
-
269
- writer .write ("return contents;" );
270
- }
271
-
272
- private void writeDocumentStructureMemberDeserialization (
273
- GenerationContext context ,
274
- String memberName ,
275
- String locationName ,
276
- MemberShape member
277
- ) {
278
- TypeScriptWriter writer = context .getWriter ();
279
- Shape target = context .getModel ().getShapeIndex ().getShape (member .getTarget ()).get ();
280
-
281
- // Generate an if statement to set the bodyParam if the member is set.
282
- writer .openBlock ("if (output.$L !== undefined) {" , "}" , locationName , () -> {
283
- writer .write ("contents.$L = $L;" , memberName ,
284
- // Dispatch to the output value provider for any additional handling.
285
- getOutputValue (context , Location .DOCUMENT , "output." + locationName , member , target ));
286
- });
287
- }
288
-
289
- @ Override
290
- protected void deserializeDocumentCollection (GenerationContext context , CollectionShape shape ) {
291
- TypeScriptWriter writer = context .getWriter ();
292
- Shape target = context .getModel ().getShapeIndex ().getShape (shape .getMember ().getTarget ()).get ();
293
-
294
- // Dispatch to the output value provider for any additional handling.
295
- writer .openBlock ("return (output || []).map((entry: any) =>" , ");" , () -> {
296
- writer .write (getOutputValue (context , Location .DOCUMENT , "entry" , shape .getMember (), target ));
297
- });
298
- }
299
-
300
- @ Override
301
- protected void deserializeDocumentMap (GenerationContext context , MapShape shape ) {
302
- TypeScriptWriter writer = context .getWriter ();
303
- Shape target = context .getModel ().getShapeIndex ().getShape (shape .getValue ().getTarget ()).get ();
304
-
305
- // Get the right serialization for each entry in the map. Undefined
306
- // outputs won't have this deserializer invoked.
307
- writer .write ("let mapParams: any = {};" );
308
- writer .openBlock ("Object.keys(output).forEach(key => {" , "});" , () -> {
309
- writer .write ("mapParams[key] = $L;" ,
310
- // Dispatch to the output value provider for any additional handling.
311
- getOutputValue (context , Location .DOCUMENT , "output[key]" , shape .getValue (), target ));
312
- });
313
- writer .write ("return mapParams;" );
314
- }
315
-
316
- @ Override
317
- protected void deserializeDocumentUnion (GenerationContext context , UnionShape shape ) {
318
- TypeScriptWriter writer = context .getWriter ();
319
- ShapeIndex index = context .getModel ().getShapeIndex ();
320
-
321
- // Check for any known union members and return when we find one.
322
- Map <String , MemberShape > members = new TreeMap <>(shape .getAllMembers ());
323
- members .forEach ((memberName , memberShape ) -> {
324
- Shape target = index .getShape (memberShape .getTarget ()).get ();
325
- // Use the jsonName trait value if present, otherwise use the member name.
326
- String locationName = memberShape .getTrait (JsonNameTrait .class )
327
- .map (JsonNameTrait ::getValue )
328
- .orElse (memberName );
329
- writer .openBlock ("if (output.$L !== undefined) {" , "}" , locationName , () -> {
330
- writer .openBlock ("return {" , "};" , () -> {
331
- // Dispatch to the output value provider for any additional handling.
332
- writer .write ("$L: $L" , memberName , getOutputValue (context , Location .DOCUMENT ,
333
- "output." + locationName , memberShape , target ));
334
- });
335
- });
336
- });
337
- // Or write to the unknown member the element in the output.
338
- writer .write ("return { $$unknown: output[Object.keys(output)[0]] };" );
339
- }
340
36
}
0 commit comments