(celType *Type, paths []*fieldPath)
| 65 | } |
| 66 | |
| 67 | func (b *backtrack) expandFieldPaths(celType *Type, paths []*fieldPath) []*fieldPath { |
| 68 | if slices.ContainsFunc(b.types[:len(b.types)-1], func(t *Type) bool { return t.String() == celType.String() }) { |
| 69 | // Cycle detected, so stop expanding. |
| 70 | paths[len(paths)-1].isLeaf = false |
| 71 | return paths |
| 72 | } |
| 73 | switch celType.Kind() { |
| 74 | case types.StructKind: |
| 75 | fields, ok := b.provider.FindStructFieldNames(celType.String()) |
| 76 | if !ok { |
| 77 | // Caller added this type to the path, so it must be a leaf. |
| 78 | paths[len(paths)-1].isLeaf = true |
| 79 | return paths |
| 80 | } |
| 81 | for _, field := range fields { |
| 82 | fieldType, ok := b.provider.FindStructFieldType(celType.String(), field) |
| 83 | if !ok { |
| 84 | // Field not found, either hidden or an error. |
| 85 | continue |
| 86 | } |
| 87 | b.push(field, celType) |
| 88 | description := "" |
| 89 | if docProvider, ok := b.provider.(documentationProvider); ok { |
| 90 | description, _ = docProvider.FindStructFieldDescription(celType.String(), field) |
| 91 | } |
| 92 | path := &fieldPath{ |
| 93 | celType: fieldType.Type, |
| 94 | path: formatPath(b.path), |
| 95 | description: description, |
| 96 | isLeaf: false, |
| 97 | } |
| 98 | paths = append(paths, path) |
| 99 | paths = b.expandFieldPaths(fieldType.Type, paths) |
| 100 | b.pop() |
| 101 | } |
| 102 | return paths |
| 103 | case types.MapKind: |
| 104 | if len(celType.Parameters()) != 2 { |
| 105 | // dynamic map, so treat as a leaf. |
| 106 | paths[len(paths)-1].isLeaf = true |
| 107 | return paths |
| 108 | } |
| 109 | mapKeyType := celType.Parameters()[0] |
| 110 | mapValueType := celType.Parameters()[1] |
| 111 | // Add a placeholder for the map key kind (the zero value). |
| 112 | keyIdentifier := "" |
| 113 | switch mapKeyType.Kind() { |
| 114 | case types.StringKind: |
| 115 | keyIdentifier = "[\"\"]" |
| 116 | case types.IntKind: |
| 117 | keyIdentifier = "[0]" |
| 118 | case types.UintKind: |
| 119 | keyIdentifier = "[0u]" |
| 120 | case types.BoolKind: |
| 121 | keyIdentifier = "[false]" |
| 122 | default: |
| 123 | // Caller added this type to the path, so it must be a leaf. |
| 124 | paths[len(paths)-1].isLeaf = true |
no test coverage detected