Validate checks that the response definition is consistent: its status is set and the result type definition if any is valid.
(e *GRPCEndpointExpr)
| 62 | // Validate checks that the response definition is consistent: its status is set |
| 63 | // and the result type definition if any is valid. |
| 64 | func (r *GRPCResponseExpr) Validate(e *GRPCEndpointExpr) *eval.ValidationErrors { |
| 65 | verr := new(eval.ValidationErrors) |
| 66 | |
| 67 | var hasMessage, hasHeaders, hasTrailers bool |
| 68 | if r.Message.Type != Empty { |
| 69 | hasMessage = true |
| 70 | verr.Merge(r.Message.Validate("gRPC response message", r)) |
| 71 | verr.Merge(validateMessage(r.Message, e.MethodExpr.Result, e, false)) |
| 72 | } |
| 73 | if !r.Headers.IsEmpty() { |
| 74 | hasHeaders = true |
| 75 | verr.Merge(r.Headers.Validate("gRPC response header metadata", r)) |
| 76 | verr.Merge(validateMetadata(r.Headers, e.MethodExpr.Result, e, false)) |
| 77 | } |
| 78 | if !r.Trailers.IsEmpty() { |
| 79 | hasTrailers = true |
| 80 | verr.Merge(r.Trailers.Validate("gRPC response trailer metadata", r)) |
| 81 | verr.Merge(validateMetadata(r.Trailers, e.MethodExpr.Result, e, false)) |
| 82 | } |
| 83 | |
| 84 | if robj := AsObject(e.MethodExpr.Result.Type); robj != nil { |
| 85 | switch { |
| 86 | case hasMessage && hasHeaders: |
| 87 | // ensure the attributes defined in message are not defined in |
| 88 | // header metadata. |
| 89 | metObj := AsObject(r.Headers.Type) |
| 90 | for _, nat := range *AsObject(r.Message.Type) { |
| 91 | if metObj.Attribute(nat.Name) != nil { |
| 92 | verr.Add(e, "Attribute %q defined in both response message and header metadata. Define the attribute in either message or header metadata.", nat.Name) |
| 93 | } |
| 94 | } |
| 95 | case hasMessage && hasTrailers: |
| 96 | // ensure the attributes defined in message are not defined in |
| 97 | // trailer metadata. |
| 98 | metObj := AsObject(r.Trailers.Type) |
| 99 | for _, nat := range *AsObject(r.Message.Type) { |
| 100 | if metObj.Attribute(nat.Name) != nil { |
| 101 | verr.Add(e, "Attribute %q defined in both response message and trailer metadata. Define the attribute in either message or trailer metadata.", nat.Name) |
| 102 | } |
| 103 | } |
| 104 | case hasHeaders && hasTrailers: |
| 105 | // ensure the attributes defined in header metadata are not defined in |
| 106 | // trailer metadata |
| 107 | hdrObj := AsObject(r.Headers.Type) |
| 108 | for _, nat := range *AsObject(r.Trailers.Type) { |
| 109 | if hdrObj.Attribute(nat.Name) != nil { |
| 110 | verr.Add(e, "Attribute %q defined in both response header and trailer metadata. Define the attribute in either header or trailer metadata.", nat.Name) |
| 111 | } |
| 112 | } |
| 113 | case !hasMessage && !hasHeaders && !hasTrailers: |
| 114 | // no response message or metadata is defined. Ensure that the method |
| 115 | // result attributes have "rpc:tag" set |
| 116 | verr.Merge(validateRPCTags(robj, e)) |
| 117 | } |
| 118 | } else { |
| 119 | switch { |
| 120 | case hasMessage && hasHeaders: |
| 121 | verr.Add(e, "Both response message and header metadata are defined, but result is not an object. Define either header metadata or message or make result an object type.") |
nothing calls this directly
no test coverage detected