66
77import java .time .Instant ;
88import java .util .Iterator ;
9+ import java .util .LinkedHashSet ;
910import software .amazon .smithy .codegen .core .Symbol ;
1011import software .amazon .smithy .codegen .core .SymbolProvider ;
1112import software .amazon .smithy .model .Model ;
3536import software .amazon .smithy .model .shapes .TimestampShape ;
3637import software .amazon .smithy .model .shapes .UnionShape ;
3738import software .amazon .smithy .model .traits .TimestampFormatTrait ;
39+ import software .amazon .smithy .model .traits .UniqueItemsTrait ;
3840import software .amazon .smithy .traitcodegen .SymbolProperties ;
3941import software .amazon .smithy .traitcodegen .TraitCodegenUtils ;
4042import software .amazon .smithy .traitcodegen .writer .TraitCodegenWriter ;
41- import software .amazon .smithy .utils .StringUtils ;
4243
4344/**
4445 * Generates the static {@code fromNode} method to deserialize a smithy node into an instance of a Java class.
@@ -82,7 +83,8 @@ public Void listShape(ListShape shape) {
8283 Node .class ,
8384 () -> {
8485 writer .writeWithNoFormatting ("Builder builder = builder();" );
85- shape .accept (new FromNodeMapperVisitor (writer , model , "node" ));
86+ shape .accept (new FromNodeMapperVisitor (writer , model , "node" , symbolProvider ));
87+ writer .write ("builder.values(value0);" );
8688 writer .writeWithNoFormatting ("return builder.build();" );
8789 });
8890 writer .newLine ();
@@ -99,7 +101,7 @@ public Void mapShape(MapShape shape) {
99101 Node .class ,
100102 () -> {
101103 writer .writeWithNoFormatting ("Builder builder = builder();" );
102- shape .accept (new FromNodeMapperVisitor (writer , model , "node" ));
104+ shape .accept (new FromNodeMapperVisitor (writer , model , "node" , symbolProvider ));
103105 writer .writeWithNoFormatting ("return builder.build();" );
104106 });
105107 writer .newLine ();
@@ -169,7 +171,7 @@ public Void structureShape(StructureShape shape) {
169171 if (memberIterator .hasNext ()) {
170172 writer .writeInlineWithNoFormatting ("\n " );
171173 } else {
172- writer .writeWithNoFormatting (";\n " );
174+ writer .writeInlineWithNoFormatting (";\n " );
173175 }
174176 }
175177 writer .dedent ();
@@ -200,7 +202,7 @@ private void writeTimestampDeser() {
200202 if (shape .hasTrait (TimestampFormatTrait .ID )) {
201203 writer .write ("return new $T($C, node.getSourceLocation());" ,
202204 symbol ,
203- (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "node" )));
205+ (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "node" , symbolProvider )));
204206 } else {
205207 writer .openBlock ("if (node.isNumberNode()) {" , "}" , () -> {
206208 writer .write ("return new $T($T.ofEpochSecond(node.expectNumberNode().getValue().longValue())," ,
@@ -251,10 +253,30 @@ public Void booleanShape(BooleanShape shape) {
251253
252254 @ Override
253255 public Void listShape (ListShape shape ) {
254- writer .writeInline (memberPrefix + "ArrayMember($1S, n -> $3C, builder::$2L)" ,
255- fieldName ,
256- memberName ,
257- (Runnable ) () -> shape .getMember ().accept (new FromNodeMapperVisitor (writer , model , "n" , 1 )));
256+ writer .writeInline (memberPrefix + "ArrayMember($1S, n -> " , fieldName );
257+
258+ Shape memberTarget = model .expectShape (shape .getMember ().getTarget ());
259+ boolean isMemberCollection = memberTarget .isListShape () || memberTarget .isMapShape ();
260+ if (isMemberCollection ) {
261+ writer .indent ();
262+ writer .writeInline ("{\n $C\n " ,
263+ (Runnable ) () -> shape .getMember ()
264+ .accept (new FromNodeMapperVisitor (writer , model , "n" , 1 , symbolProvider )));
265+ writer .writeInlineWithNoFormatting ("return value1;\n " );
266+ writer .dedent ();
267+ writer .writeInlineWithNoFormatting ("}, " );
268+ } else {
269+ writer .writeInline ("$C, " ,
270+ (Runnable ) () -> shape .getMember ()
271+ .accept (new FromNodeMapperVisitor (writer , model , "n" , 1 , symbolProvider )));
272+ }
273+
274+ boolean isSet = shape .hasTrait (UniqueItemsTrait .ID );
275+ if (isSet ) {
276+ writer .writeInline ("l -> builder.$L(new $T<>(l)))" , fieldName , LinkedHashSet .class );
277+ } else {
278+ writer .writeInline ("builder::$L)" , fieldName );
279+ }
258280 return null ;
259281 }
260282
@@ -335,29 +357,13 @@ public Void bigDecimalShape(BigDecimalShape shape) {
335357
336358 @ Override
337359 public Void mapShape (MapShape shape ) {
338- writer .disableNewlines ();
339- writer .openBlock (memberPrefix
340- + "ObjectMember($S, o -> o.getMembers().forEach((k, v) -> {\n " ,
341- "}))" ,
342- fieldName ,
343- () -> {
344- writer .write ("builder.put$L(\n " , StringUtils .capitalize (memberName ));
345- writer .indent ();
346- writer .write ("$C,\n " ,
347- (Runnable ) () -> shape .getKey ()
348- .accept (new FromNodeMapperVisitor (writer ,
349- model ,
350- "k" )));
351- writer .write ("$C\n " ,
352- (Runnable ) () -> shape .getValue ()
353- .accept (new FromNodeMapperVisitor (writer ,
354- model ,
355- "v" ,
356- 1 )));
357- writer .dedent ();
358- writer .write (");\n " );
359- });
360- writer .enableNewlines ();
360+ writer .writeInline (memberPrefix + "ObjectMember($S, o -> {\n " , fieldName );
361+ writer .indent ();
362+ writer .writeInline ("$C\n " ,
363+ (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "o" , 1 , symbolProvider )));
364+ writer .writeInline ("builder.$L(value1);" , memberName );
365+ writer .dedent ();
366+ writer .writeInlineWithNoFormatting ("\n })" );
361367 return null ;
362368 }
363369
@@ -378,7 +384,7 @@ public Void stringShape(StringShape shape) {
378384 writer .writeInline (memberPrefix + "Member($1S, n -> $3C, builder::$2L)" ,
379385 fieldName ,
380386 memberName ,
381- (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "n" )));
387+ (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "n" , symbolProvider )));
382388 }
383389 return null ;
384390 }
@@ -397,7 +403,7 @@ public Void structureShape(StructureShape shape) {
397403 writer .writeInline (memberPrefix + "Member($1S, n -> $3C, builder::$2L)" ,
398404 fieldName ,
399405 memberName ,
400- (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "n" )));
406+ (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "n" , symbolProvider )));
401407 return null ;
402408 }
403409
@@ -406,7 +412,7 @@ public Void timestampShape(TimestampShape shape) {
406412 writer .writeInline (memberPrefix + "Member($1S, n -> $3C, builder::$2L)" ,
407413 fieldName ,
408414 memberName ,
409- (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "n" )));
415+ (Runnable ) () -> shape .accept (new FromNodeMapperVisitor (writer , model , "n" , symbolProvider )));
410416 return null ;
411417 }
412418
0 commit comments