18
18
import java .util .List ;
19
19
import software .amazon .smithy .codegen .core .SymbolProvider ;
20
20
import software .amazon .smithy .model .knowledge .HttpBinding ;
21
+ import software .amazon .smithy .model .knowledge .HttpBinding .Location ;
22
+ import software .amazon .smithy .model .shapes .CollectionShape ;
23
+ import software .amazon .smithy .model .shapes .MapShape ;
24
+ import software .amazon .smithy .model .shapes .MemberShape ;
21
25
import software .amazon .smithy .model .shapes .OperationShape ;
26
+ import software .amazon .smithy .model .shapes .Shape ;
27
+ import software .amazon .smithy .model .shapes .ShapeIndex ;
28
+ import software .amazon .smithy .model .shapes .SimpleShape ;
29
+ import software .amazon .smithy .model .shapes .StructureShape ;
30
+ import software .amazon .smithy .model .shapes .UnionShape ;
22
31
import software .amazon .smithy .model .traits .JsonNameTrait ;
32
+ import software .amazon .smithy .model .traits .TimestampFormatTrait .Format ;
23
33
import software .amazon .smithy .typescript .codegen .TypeScriptWriter ;
24
34
import software .amazon .smithy .typescript .codegen .integration .HttpBindingProtocolGenerator ;
25
35
@@ -35,6 +45,11 @@ protected String getDocumentContentType() {
35
45
return "application/x-amz-json-1.1" ;
36
46
}
37
47
48
+ @ Override
49
+ protected Format getDocumentTimestampFormat () {
50
+ return Format .EPOCH_SECONDS ;
51
+ }
52
+
38
53
@ Override
39
54
protected void serializeDocument (
40
55
GenerationContext context ,
@@ -52,14 +67,105 @@ protected void serializeDocument(
52
67
String locationName = binding .getMember ().getTrait (JsonNameTrait .class )
53
68
.map (JsonNameTrait ::getValue )
54
69
.orElseGet (binding ::getLocationName );
55
- writer .openBlock ("if (input.$L !== undefined) {" , "}" , memberName , () -> {
56
- // TODO: walk the input to serialize appropriately.
57
- // TODO: we need to serialize Date values as epoch-seconds.
58
- // TODO: we need to serialize blob values as base64 encoded strings.
59
- writer .write ("bodyParams['$L'] = input.$L;" , locationName , memberName );
60
- });
70
+ writeDocumentStructureMemberSerialization (context , operation ,
71
+ memberName , locationName , binding .getMember ());
61
72
}
62
73
63
74
writer .write ("body = JSON.stringify(bodyParams);" );
64
75
}
76
+
77
+ @ Override
78
+ protected void serializeDocumentStructure (GenerationContext context , StructureShape shape ) {
79
+ TypeScriptWriter writer = context .getWriter ();
80
+
81
+ writer .write ("let bodyParams: any = {};" );
82
+ shape .getAllMembers ().forEach ((memberName , memberShape ) -> {
83
+ // Use the jsonName trait value if present, otherwise use the member name.
84
+ String locationName = memberShape .getTrait (JsonNameTrait .class )
85
+ .map (JsonNameTrait ::getValue )
86
+ .orElse (memberName );
87
+ writeDocumentStructureMemberSerialization (context , shape , memberName , locationName , memberShape );
88
+ });
89
+ writer .write ("return bodyParams;" );
90
+ }
91
+
92
+ private void writeDocumentStructureMemberSerialization (
93
+ GenerationContext context ,
94
+ Shape container ,
95
+ String memberName ,
96
+ String locationName ,
97
+ MemberShape member
98
+ ) {
99
+ TypeScriptWriter writer = context .getWriter ();
100
+ Shape target = context .getModel ().getShapeIndex ().getShape (member .getTarget ()).get ();
101
+
102
+ // Generate an if statement to set the bodyParam if the member is set.
103
+ writer .openBlock ("if (input.$L !== undefined) {" , "}" , memberName , () -> {
104
+ writer .write ("bodyParams['$L'] = $L;" , locationName ,
105
+ getInputValue (context , Location .DOCUMENT , container , member , target ));
106
+ });
107
+ }
108
+
109
+ @ Override
110
+ protected void serializeDocumentCollection (GenerationContext context , CollectionShape shape ) {
111
+ TypeScriptWriter writer = context .getWriter ();
112
+ Shape target = context .getModel ().getShapeIndex ().getShape (shape .getMember ().getTarget ()).get ();
113
+
114
+ // Validate we have input, then get the right serialization for the member target.
115
+ writer .write ("input &&" );
116
+ writer .openBlock ("input.map(entry =>" , ");" , () -> {
117
+ writer .write (getInputValue (context , Location .DOCUMENT , shape , shape .getMember (), target ));
118
+ });
119
+ }
120
+
121
+ @ Override
122
+ protected void serializeDocumentMap (GenerationContext context , MapShape shape ) {
123
+ TypeScriptWriter writer = context .getWriter ();
124
+ Shape target = context .getModel ().getShapeIndex ().getShape (shape .getValue ().getTarget ()).get ();
125
+
126
+ // Validate we have input, then get the right serialization for the map value.
127
+ writer .write ("input.name &&" );
128
+ writer .openBlock ("input.value && {" , "};" , () -> {
129
+ writer .write ("name: input.name," );
130
+ writer .write ("value: $L" , getInputValue (context , Location .DOCUMENT , shape , shape .getValue (), target ));
131
+ });
132
+ }
133
+
134
+ // TODO Collection cleanup point
135
+ // This, and the location it is invoked, can be cleaned up if/when a
136
+ // centralized way to check for and/or handle these differences is built.
137
+ private boolean isSimpleCollection (ShapeIndex index , Shape shape ) {
138
+ if (shape instanceof CollectionShape ) {
139
+ Shape target = index .getShape (((CollectionShape ) shape ).getMember ().getTarget ()).get ();
140
+ if (target instanceof CollectionShape ) {
141
+ return isSimpleCollection (index , target );
142
+ }
143
+ return target instanceof SimpleShape ;
144
+ }
145
+ return false ;
146
+ }
147
+
148
+ @ Override
149
+ protected void serializeDocumentUnion (GenerationContext context , UnionShape shape ) {
150
+ SymbolProvider symbolProvider = context .getSymbolProvider ();
151
+ TypeScriptWriter writer = context .getWriter ();
152
+ ShapeIndex index = context .getModel ().getShapeIndex ();
153
+
154
+ // Visit over the union type, then get the right serialization for the member.
155
+ writer .openBlock ("$L.visit(input, {" , "});" , shape .getId ().getName (), () -> {
156
+ shape .getAllMembers ().forEach ((name , member ) -> {
157
+ writer .openBlock ("$L: value => {" , "}," , symbolProvider .toMemberName (member ), () -> {
158
+ Shape target = index .getShape (member .getTarget ()).get ();
159
+ // TODO See collection cleanup note
160
+ // Make sure we invoke the other serialization of union members that need it.
161
+ if (!(target instanceof SimpleShape ) && !isSimpleCollection (index , target )) {
162
+ writer .write ("$L;" , getInputValue (context , Location .DOCUMENT , shape , member , target ));
163
+ } else {
164
+ writer .write ("value;" );
165
+ }
166
+ });
167
+ });
168
+ writer .openBlock ("_: value => {" , "}" , () -> writer .write ("value;" ));
169
+ });
170
+ }
65
171
}
0 commit comments