|
14 | 14 | package model
|
15 | 15 |
|
16 | 16 | import (
|
| 17 | + "errors" |
17 | 18 | "fmt"
|
18 | 19 | "sort"
|
19 | 20 | "strings"
|
@@ -400,6 +401,81 @@ func (r *CRD) GetOutputWrapperFieldPath(
|
400 | 401 | return &opConfig.OutputWrapperFieldPath
|
401 | 402 | }
|
402 | 403 |
|
| 404 | +// GetOutputShape returns the Output shape for given operation. |
| 405 | +func (r *CRD) GetOutputShape( |
| 406 | + // The operation to look for the Output shape |
| 407 | + op *awssdkmodel.Operation, |
| 408 | +) (*awssdkmodel.Shape, error) { |
| 409 | + if op == nil { |
| 410 | + return nil, errors.New("no output shape for nil operation") |
| 411 | + } |
| 412 | + |
| 413 | + outputShape := op.OutputRef.Shape |
| 414 | + if outputShape == nil { |
| 415 | + return nil, errors.New("output shape not found") |
| 416 | + } |
| 417 | + |
| 418 | + // We might be in a "wrapper" shape. Unwrap it to find the real object |
| 419 | + // representation for the CRD's createOp/DescribeOP. |
| 420 | + |
| 421 | + // Use the wrapper field path if it's given in the ack-generate config file. |
| 422 | + wrapperFieldPath := r.GetOutputWrapperFieldPath(op) |
| 423 | + if wrapperFieldPath != nil { |
| 424 | + wrapperOutputShape, err := r.GetWrapperOutputShape(outputShape, *wrapperFieldPath) |
| 425 | + if err != nil { |
| 426 | + return nil, fmt.Errorf("unable to unwrap the output shape: %v", err) |
| 427 | + } |
| 428 | + outputShape = wrapperOutputShape |
| 429 | + } else { |
| 430 | + // If the wrapper field path is not specified in the config file and if |
| 431 | + // there is a single member shape and that member shape is a structure, |
| 432 | + // unwrap it. |
| 433 | + if outputShape.UsedAsOutput && len(outputShape.MemberRefs) == 1 { |
| 434 | + for _, memberRef := range outputShape.MemberRefs { |
| 435 | + if memberRef.Shape.Type == "structure" { |
| 436 | + outputShape = memberRef.Shape |
| 437 | + } |
| 438 | + } |
| 439 | + } |
| 440 | + } |
| 441 | + return outputShape, nil |
| 442 | +} |
| 443 | + |
| 444 | +// GetWrapperOutputShape returns the shape of the last element of a given field |
| 445 | +// Path. It carefully unwraps the output shape and verifies that every element |
| 446 | +// of the field path exists in their correspanding parent shape and that they are |
| 447 | +// structures. |
| 448 | +func (r *CRD) GetWrapperOutputShape( |
| 449 | + shape *awssdkmodel.Shape, |
| 450 | + fieldPath string, |
| 451 | +) (*awssdkmodel.Shape, error) { |
| 452 | + if fieldPath == "" { |
| 453 | + return shape, nil |
| 454 | + } |
| 455 | + fieldPathParts := strings.Split(fieldPath, ".") |
| 456 | + for x, wrapperField := range fieldPathParts { |
| 457 | + for memberName, memberRef := range shape.MemberRefs { |
| 458 | + if memberName == wrapperField { |
| 459 | + if memberRef.Shape.Type != "structure" { |
| 460 | + // All the mentionned shapes must be structure |
| 461 | + return nil, fmt.Errorf( |
| 462 | + "Expected SetOutput.WrapperFieldPath to only contain fields of type 'structure'."+ |
| 463 | + " Found %s of type '%s'", |
| 464 | + memberName, memberRef.Shape.Type, |
| 465 | + ) |
| 466 | + } |
| 467 | + remainPath := strings.Join(fieldPathParts[x+1:], ".") |
| 468 | + return r.GetWrapperOutputShape(memberRef.Shape, remainPath) |
| 469 | + } |
| 470 | + } |
| 471 | + return nil, fmt.Errorf( |
| 472 | + "Incorrect SetOutput.WrapperFieldPath. Could not find %s in Shape %s", |
| 473 | + wrapperField, shape.ShapeName, |
| 474 | + ) |
| 475 | + } |
| 476 | + return shape, nil |
| 477 | +} |
| 478 | + |
403 | 479 | // GetCustomImplementation returns custom implementation method name for the
|
404 | 480 | // supplied operation as specified in generator config
|
405 | 481 | func (r *CRD) GetCustomImplementation(
|
|
0 commit comments