| 176 | } |
| 177 | |
| 178 | func mapDepth(dt expr.DataType, depth int, seen ...map[string]struct{}) int { |
| 179 | if mp := expr.AsMap(dt); mp != nil { |
| 180 | depth++ |
| 181 | depth = mapDepth(mp.ElemType.Type, depth, seen...) |
| 182 | } else if ar := expr.AsArray(dt); ar != nil { |
| 183 | depth = mapDepth(ar.ElemType.Type, depth, seen...) |
| 184 | } else if mo := expr.AsObject(dt); mo != nil { |
| 185 | var s map[string]struct{} |
| 186 | if len(seen) > 0 { |
| 187 | s = seen[0] |
| 188 | } else { |
| 189 | s = make(map[string]struct{}) |
| 190 | seen = append(seen, s) |
| 191 | } |
| 192 | key := dt.Name() |
| 193 | if u, ok := dt.(expr.UserType); ok { |
| 194 | key = u.ID() |
| 195 | } |
| 196 | if _, ok := s[key]; ok { |
| 197 | return depth |
| 198 | } |
| 199 | s[key] = struct{}{} |
| 200 | var level int |
| 201 | for _, nat := range *mo { |
| 202 | // if object type has attributes of type map then find out the attribute that has |
| 203 | // the deepest level of nested maps |
| 204 | lvl := 0 |
| 205 | lvl = mapDepth(nat.Attribute.Type, lvl, seen...) |
| 206 | if lvl > level { |
| 207 | level = lvl |
| 208 | } |
| 209 | } |
| 210 | depth += level |
| 211 | } |
| 212 | return depth |
| 213 | } |
| 214 | |
| 215 | // IsPrimitivePointer returns true if the attribute with the given name is a |
| 216 | // primitive pointer in the given parent attribute. |