@@ -226,6 +226,10 @@ func (g *Generator) GetCRDs() ([]*ackmodel.CRD, error) {
226
226
sort .Slice (crds , func (i , j int ) bool {
227
227
return crds [i ].Names .Camel < crds [j ].Names .Camel
228
228
})
229
+ // This is the place that we build out the CRD.Fields map with
230
+ // `pkg/model.Field` objects that represent the non-top-level Spec and
231
+ // Status fields.
232
+ g .processNestedFields (crds )
229
233
g .crds = crds
230
234
return crds , nil
231
235
}
@@ -401,6 +405,145 @@ func (g *Generator) GetTypeDefs() ([]*ackmodel.TypeDef, map[string]string, error
401
405
return tdefs , timports , nil
402
406
}
403
407
408
+ // processNestedFields is responsible for walking all of the CRDs' Spec and
409
+ // Status fields' Shape objects and adding `pkg/model.Field` objects for all
410
+ // nested fields along with that `Field`'s `Config` object that allows us to
411
+ // determine if the TypeDef associated with that nested field should have its
412
+ // data type overridden (e.g. for SecretKeyReferences)
413
+ func (g * Generator ) processNestedFields (crds []* ackmodel.CRD ) {
414
+ for _ , crd := range crds {
415
+ for _ , field := range crd .SpecFields {
416
+ g .processNestedField (crd , field )
417
+ }
418
+ for _ , field := range crd .StatusFields {
419
+ g .processNestedField (crd , field )
420
+ }
421
+ }
422
+ }
423
+
424
+ // processNestedField processes any nested fields (non-scalar fields associated
425
+ // with the Spec and Status objects)
426
+ func (g * Generator ) processNestedField (
427
+ crd * ackmodel.CRD ,
428
+ field * ackmodel.Field ,
429
+ ) {
430
+ if field .ShapeRef == nil && (field .FieldConfig == nil || ! field .FieldConfig .IsAttribute ) {
431
+ fmt .Printf (
432
+ "WARNING: Field %s:%s has nil ShapeRef and is not defined as an Attribute-based Field!\n " ,
433
+ crd .Names .Original ,
434
+ field .Names .Original ,
435
+ )
436
+ return
437
+ }
438
+ if field .ShapeRef != nil {
439
+ fieldShape := field .ShapeRef .Shape
440
+ fieldType := fieldShape .Type
441
+ switch fieldType {
442
+ case "structure" :
443
+ g .processNestedStructField (crd , field .Path + "." , field )
444
+ case "list" :
445
+ g .processNestedListField (crd , field .Path + ".." , field )
446
+ case "map" :
447
+ g .processNestedMapField (crd , field .Path + ".." , field )
448
+ }
449
+ }
450
+ // TODO(jaypipes): Handle Attribute-based fields...
451
+ }
452
+
453
+ // processNestedStructField recurses through the members of a nested field that
454
+ // is a struct type and adds any Field objects to the supplied CRD.
455
+ func (g * Generator ) processNestedStructField (
456
+ crd * ackmodel.CRD ,
457
+ baseFieldPath string ,
458
+ baseField * ackmodel.Field ,
459
+ ) {
460
+ fieldConfigs := crd .Config ().ResourceFields (crd .Names .Original )
461
+ baseFieldShape := baseField .ShapeRef .Shape
462
+ for memberName , memberRef := range baseFieldShape .MemberRefs {
463
+ memberNames := names .New (memberName )
464
+ memberShape := memberRef .Shape
465
+ memberShapeType := memberShape .Type
466
+ fieldPath := baseFieldPath + memberNames .Camel
467
+ fieldConfig := fieldConfigs [fieldPath ]
468
+ field := ackmodel .NewField (crd , fieldPath , memberNames , memberRef , fieldConfig )
469
+ switch memberShapeType {
470
+ case "structure" :
471
+ g .processNestedStructField (crd , fieldPath + "." , field )
472
+ case "list" :
473
+ g .processNestedListField (crd , fieldPath + ".." , field )
474
+ case "map" :
475
+ g .processNestedMapField (crd , fieldPath + ".." , field )
476
+ }
477
+ crd .Fields [fieldPath ] = field
478
+ }
479
+ }
480
+
481
+ // processNestedListField recurses through the members of a nested field that
482
+ // is a list type that has a struct element type and adds any Field objects to
483
+ // the supplied CRD.
484
+ func (g * Generator ) processNestedListField (
485
+ crd * ackmodel.CRD ,
486
+ baseFieldPath string ,
487
+ baseField * ackmodel.Field ,
488
+ ) {
489
+ baseFieldShape := baseField .ShapeRef .Shape
490
+ elementFieldShape := baseFieldShape .MemberRef .Shape
491
+ if elementFieldShape .Type != "structure" {
492
+ return
493
+ }
494
+ fieldConfigs := crd .Config ().ResourceFields (crd .Names .Original )
495
+ for memberName , memberRef := range elementFieldShape .MemberRefs {
496
+ memberNames := names .New (memberName )
497
+ memberShape := memberRef .Shape
498
+ memberShapeType := memberShape .Type
499
+ fieldPath := baseFieldPath + memberNames .Camel
500
+ fieldConfig := fieldConfigs [fieldPath ]
501
+ field := ackmodel .NewField (crd , fieldPath , memberNames , memberRef , fieldConfig )
502
+ switch memberShapeType {
503
+ case "structure" :
504
+ g .processNestedStructField (crd , fieldPath + "." , field )
505
+ case "list" :
506
+ g .processNestedListField (crd , fieldPath + ".." , field )
507
+ case "map" :
508
+ g .processNestedMapField (crd , fieldPath + ".." , field )
509
+ }
510
+ crd .Fields [fieldPath ] = field
511
+ }
512
+ }
513
+
514
+ // processNestedMapField recurses through the members of a nested field that
515
+ // is a map type that has a struct value type and adds any Field objects to
516
+ // the supplied CRD.
517
+ func (g * Generator ) processNestedMapField (
518
+ crd * ackmodel.CRD ,
519
+ baseFieldPath string ,
520
+ baseField * ackmodel.Field ,
521
+ ) {
522
+ baseFieldShape := baseField .ShapeRef .Shape
523
+ valueFieldShape := baseFieldShape .ValueRef .Shape
524
+ if valueFieldShape .Type != "structure" {
525
+ return
526
+ }
527
+ fieldConfigs := crd .Config ().ResourceFields (crd .Names .Original )
528
+ for memberName , memberRef := range valueFieldShape .MemberRefs {
529
+ memberNames := names .New (memberName )
530
+ memberShape := memberRef .Shape
531
+ memberShapeType := memberShape .Type
532
+ fieldPath := baseFieldPath + memberNames .Camel
533
+ fieldConfig := fieldConfigs [fieldPath ]
534
+ field := ackmodel .NewField (crd , fieldPath , memberNames , memberRef , fieldConfig )
535
+ switch memberShapeType {
536
+ case "structure" :
537
+ g .processNestedStructField (crd , fieldPath + "." , field )
538
+ case "list" :
539
+ g .processNestedListField (crd , fieldPath + ".." , field )
540
+ case "map" :
541
+ g .processNestedMapField (crd , fieldPath + ".." , field )
542
+ }
543
+ crd .Fields [fieldPath ] = field
544
+ }
545
+ }
546
+
404
547
// GetEnumDefs returns a slice of pointers to `ackmodel.EnumDef` structs which
405
548
// represent string fields whose value is constrained to one or more specific
406
549
// string values.
0 commit comments