| 227 | } |
| 228 | |
| 229 | func validateGRPCUnionShapes(att *AttributeExpr, parent eval.Expression, verr *eval.ValidationErrors, seenUnions map[*Union]struct{}, seenAttrs map[*AttributeExpr]struct{}) { |
| 230 | if att == nil || att.Type == nil { |
| 231 | return |
| 232 | } |
| 233 | if _, ok := seenAttrs[att]; ok { |
| 234 | return |
| 235 | } |
| 236 | seenAttrs[att] = struct{}{} |
| 237 | |
| 238 | if u := AsUnion(att.Type); u != nil { |
| 239 | if _, ok := seenUnions[u]; ok { |
| 240 | return |
| 241 | } |
| 242 | seenUnions[u] = struct{}{} |
| 243 | for _, ut := range u.Values { |
| 244 | switch { |
| 245 | case IsArray(ut.Attribute.Type): |
| 246 | verr.Add(parent, "union type %s has array elements, not supported by gRPC", u.Name()) |
| 247 | case IsMap(ut.Attribute.Type): |
| 248 | verr.Add(parent, "union type %s has map elements, not supported by gRPC", u.Name()) |
| 249 | } |
| 250 | validateGRPCUnionShapes(ut.Attribute, parent, verr, seenUnions, seenAttrs) |
| 251 | } |
| 252 | return |
| 253 | } |
| 254 | |
| 255 | if o := AsObject(att.Type); o != nil { |
| 256 | for _, nat := range *o { |
| 257 | validateGRPCUnionShapes(nat.Attribute, parent, verr, seenUnions, seenAttrs) |
| 258 | } |
| 259 | return |
| 260 | } |
| 261 | |
| 262 | if ar := AsArray(att.Type); ar != nil { |
| 263 | validateGRPCUnionShapes(ar.ElemType, parent, verr, seenUnions, seenAttrs) |
| 264 | return |
| 265 | } |
| 266 | |
| 267 | if m := AsMap(att.Type); m != nil { |
| 268 | validateGRPCUnionShapes(m.KeyType, parent, verr, seenUnions, seenAttrs) |
| 269 | validateGRPCUnionShapes(m.ElemType, parent, verr, seenUnions, seenAttrs) |
| 270 | return |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | // Finalize ensures the request and response attributes are initialized. |
| 275 | func (e *GRPCEndpointExpr) Finalize() { |