|
5 | 5 |
|
6 | 6 | package software.amazon.smithy.traitcodegen.generators;
|
7 | 7 |
|
| 8 | +import java.math.BigDecimal; |
| 9 | +import java.math.BigInteger; |
| 10 | +import java.time.Instant; |
| 11 | +import java.time.format.DateTimeFormatter; |
8 | 12 | import java.util.Iterator;
|
9 | 13 | import java.util.Optional;
|
10 | 14 | import software.amazon.smithy.codegen.core.Symbol;
|
11 | 15 | import software.amazon.smithy.codegen.core.SymbolProvider;
|
12 | 16 | import software.amazon.smithy.model.Model;
|
| 17 | +import software.amazon.smithy.model.node.Node; |
| 18 | +import software.amazon.smithy.model.shapes.BigDecimalShape; |
| 19 | +import software.amazon.smithy.model.shapes.BigIntegerShape; |
| 20 | +import software.amazon.smithy.model.shapes.BlobShape; |
| 21 | +import software.amazon.smithy.model.shapes.BooleanShape; |
| 22 | +import software.amazon.smithy.model.shapes.ByteShape; |
| 23 | +import software.amazon.smithy.model.shapes.DocumentShape; |
| 24 | +import software.amazon.smithy.model.shapes.DoubleShape; |
| 25 | +import software.amazon.smithy.model.shapes.FloatShape; |
| 26 | +import software.amazon.smithy.model.shapes.IntegerShape; |
13 | 27 | import software.amazon.smithy.model.shapes.ListShape;
|
| 28 | +import software.amazon.smithy.model.shapes.LongShape; |
14 | 29 | import software.amazon.smithy.model.shapes.MapShape;
|
15 | 30 | import software.amazon.smithy.model.shapes.MemberShape;
|
16 | 31 | import software.amazon.smithy.model.shapes.Shape;
|
17 | 32 | import software.amazon.smithy.model.shapes.ShapeType;
|
18 | 33 | import software.amazon.smithy.model.shapes.ShapeVisitor;
|
| 34 | +import software.amazon.smithy.model.shapes.ShortShape; |
| 35 | +import software.amazon.smithy.model.shapes.StringShape; |
19 | 36 | import software.amazon.smithy.model.shapes.StructureShape;
|
| 37 | +import software.amazon.smithy.model.shapes.TimestampShape; |
| 38 | +import software.amazon.smithy.model.shapes.UnionShape; |
20 | 39 | import software.amazon.smithy.model.traits.AbstractTraitBuilder;
|
| 40 | +import software.amazon.smithy.model.traits.DefaultTrait; |
21 | 41 | import software.amazon.smithy.model.traits.StringListTrait;
|
| 42 | +import software.amazon.smithy.model.traits.TimestampFormatTrait; |
22 | 43 | import software.amazon.smithy.model.traits.TraitDefinition;
|
23 | 44 | import software.amazon.smithy.traitcodegen.SymbolProperties;
|
24 | 45 | import software.amazon.smithy.traitcodegen.TraitCodegenUtils;
|
@@ -172,6 +193,13 @@ private void writeProperty(MemberShape shape) {
|
172 | 193 | symbolProvider.toSymbol(shape),
|
173 | 194 | symbolProvider.toMemberName(shape),
|
174 | 195 | builderRefOptional.orElseThrow(RuntimeException::new));
|
| 196 | + return; |
| 197 | + } |
| 198 | + |
| 199 | + if (shape.hasNonNullDefault()) { |
| 200 | + writer.write("private $B $L = $C;", symbolProvider.toSymbol(shape), |
| 201 | + symbolProvider.toMemberName(shape), |
| 202 | + new DefaultInitializerGenerator(writer, model, symbolProvider, shape)); |
175 | 203 | } else {
|
176 | 204 | writer.write("private $B $L;", symbolProvider.toSymbol(shape),
|
177 | 205 | symbolProvider.toMemberName(shape));
|
@@ -305,4 +333,161 @@ public Void memberShape(MemberShape shape) {
|
305 | 333 | return model.expectShape(shape.getTarget()).accept(this);
|
306 | 334 | }
|
307 | 335 | }
|
| 336 | + |
| 337 | + /** |
| 338 | + * Adds default values to builder properties. |
| 339 | + */ |
| 340 | + private static final class DefaultInitializerGenerator extends ShapeVisitor.DataShapeVisitor<Void> implements |
| 341 | + Runnable { |
| 342 | + private final TraitCodegenWriter writer; |
| 343 | + private final Model model; |
| 344 | + private final SymbolProvider symbolProvider; |
| 345 | + private final MemberShape member; |
| 346 | + private Node defaultValue; |
| 347 | + |
| 348 | + DefaultInitializerGenerator( |
| 349 | + TraitCodegenWriter writer, |
| 350 | + Model model, |
| 351 | + SymbolProvider symbolProvider, MemberShape member |
| 352 | + ) { |
| 353 | + this.writer = writer; |
| 354 | + this.model = model; |
| 355 | + this.symbolProvider = symbolProvider; |
| 356 | + this.member = member; |
| 357 | + } |
| 358 | + |
| 359 | + @Override |
| 360 | + public void run() { |
| 361 | + if (member.hasNonNullDefault()) { |
| 362 | + this.defaultValue = member.expectTrait(DefaultTrait.class).toNode(); |
| 363 | + member.accept(this); |
| 364 | + } |
| 365 | + } |
| 366 | + |
| 367 | + @Override |
| 368 | + public Void blobShape(BlobShape blobShape) { |
| 369 | + throw new UnsupportedOperationException("Blob default value cannot be set."); |
| 370 | + } |
| 371 | + |
| 372 | + @Override |
| 373 | + public Void booleanShape(BooleanShape booleanShape) { |
| 374 | + writer.write("$L", defaultValue.expectBooleanNode().getValue()); |
| 375 | + return null; |
| 376 | + } |
| 377 | + |
| 378 | + @Override |
| 379 | + public Void listShape(ListShape listShape) { |
| 380 | + throw new UnsupportedOperationException("List default values are not set with DefaultGenerator."); |
| 381 | + } |
| 382 | + |
| 383 | + @Override |
| 384 | + public Void mapShape(MapShape mapShape) { |
| 385 | + throw new UnsupportedOperationException("Map default values are not set with DefaultGenerator."); |
| 386 | + } |
| 387 | + |
| 388 | + @Override |
| 389 | + public Void byteShape(ByteShape byteShape) { |
| 390 | + // Bytes duplicate the integer toString method |
| 391 | + writer.write("$L", defaultValue.expectNumberNode().getValue().intValue()); |
| 392 | + return null; |
| 393 | + } |
| 394 | + |
| 395 | + @Override |
| 396 | + public Void shortShape(ShortShape shortShape) { |
| 397 | + // Shorts duplicate the int toString method |
| 398 | + writer.write("$L", defaultValue.expectNumberNode().getValue().intValue()); |
| 399 | + return null; |
| 400 | + } |
| 401 | + |
| 402 | + @Override |
| 403 | + public Void integerShape(IntegerShape integerShape) { |
| 404 | + writer.write("$L", defaultValue.expectNumberNode().getValue().intValue()); |
| 405 | + return null; |
| 406 | + } |
| 407 | + |
| 408 | + @Override |
| 409 | + public Void longShape(LongShape longShape) { |
| 410 | + writer.write("$LL", defaultValue.expectNumberNode().getValue().longValue()); |
| 411 | + return null; |
| 412 | + } |
| 413 | + |
| 414 | + @Override |
| 415 | + public Void floatShape(FloatShape floatShape) { |
| 416 | + writer.write("$Lf", defaultValue.expectNumberNode().getValue().floatValue()); |
| 417 | + return null; |
| 418 | + } |
| 419 | + |
| 420 | + @Override |
| 421 | + public Void documentShape(DocumentShape documentShape) { |
| 422 | + throw new UnsupportedOperationException("Document shape defaults cannot be set."); |
| 423 | + } |
| 424 | + |
| 425 | + @Override |
| 426 | + public Void doubleShape(DoubleShape doubleShape) { |
| 427 | + writer.write("$L", defaultValue.expectNumberNode().getValue().doubleValue()); |
| 428 | + return null; |
| 429 | + } |
| 430 | + |
| 431 | + @Override |
| 432 | + public Void bigIntegerShape(BigIntegerShape bigIntegerShape) { |
| 433 | + writer.write("$T.valueOf($L)", BigInteger.class, defaultValue.expectNumberNode().getValue().intValue()); |
| 434 | + return null; |
| 435 | + } |
| 436 | + |
| 437 | + @Override |
| 438 | + public Void bigDecimalShape(BigDecimalShape bigDecimalShape) { |
| 439 | + writer.write("$T.valueOf($L)", BigDecimal.class, defaultValue.expectNumberNode().getValue().doubleValue()); |
| 440 | + return null; |
| 441 | + } |
| 442 | + |
| 443 | + @Override |
| 444 | + public Void stringShape(StringShape stringShape) { |
| 445 | + writer.write("$S", defaultValue.expectStringNode().getValue()); |
| 446 | + return null; |
| 447 | + } |
| 448 | + |
| 449 | + @Override |
| 450 | + public Void structureShape(StructureShape structureShape) { |
| 451 | + throw new UnsupportedOperationException("Structure shape defaults cannot be set."); |
| 452 | + } |
| 453 | + |
| 454 | + @Override |
| 455 | + public Void unionShape(UnionShape unionShape) { |
| 456 | + throw new UnsupportedOperationException("Union shape defaults cannot be set."); |
| 457 | + |
| 458 | + } |
| 459 | + |
| 460 | + @Override |
| 461 | + public Void memberShape(MemberShape memberShape) { |
| 462 | + return model.expectShape(memberShape.getTarget()).accept(this); |
| 463 | + } |
| 464 | + |
| 465 | + @Override |
| 466 | + public Void timestampShape(TimestampShape timestampShape) { |
| 467 | + if (member.hasTrait(TimestampFormatTrait.class)) { |
| 468 | + switch (member.expectTrait(TimestampFormatTrait.class).getFormat()) { |
| 469 | + case EPOCH_SECONDS: |
| 470 | + writer.writeInline( |
| 471 | + "$T.ofEpochSecond($LL)", |
| 472 | + Instant.class, |
| 473 | + defaultValue.expectNumberNode().getValue().longValue() |
| 474 | + ); |
| 475 | + return null; |
| 476 | + case HTTP_DATE: |
| 477 | + writer.writeInline( |
| 478 | + "$T.from($T.RFC_1123_DATE_TIME.parse($S))", |
| 479 | + Instant.class, |
| 480 | + DateTimeFormatter.class, |
| 481 | + defaultValue.expectStringNode().getValue() |
| 482 | + ); |
| 483 | + return null; |
| 484 | + default: |
| 485 | + // Fall through on default |
| 486 | + break; |
| 487 | + } |
| 488 | + } |
| 489 | + writer.write("$T.parse($S)", Instant.class, defaultValue.expectStringNode().getValue()); |
| 490 | + return null; |
| 491 | + } |
| 492 | + } |
308 | 493 | }
|
0 commit comments