validateMessage validates the gRPC message. It compares the given message with the service type (Payload or Result) and ensures all the attributes defined in the message type are found in the service type and the attributes are set with unique "rpc:tag" numbers. msgAtt is the Request/Response messa
(msgAtt, serviceAtt *AttributeExpr, e *GRPCEndpointExpr, req bool)
| 424 | // e is the endpoint expression. |
| 425 | // req if true indicates the Request message is being validated. |
| 426 | func validateMessage(msgAtt, serviceAtt *AttributeExpr, e *GRPCEndpointExpr, req bool) *eval.ValidationErrors { |
| 427 | verr := new(eval.ValidationErrors) |
| 428 | msgKind := "Response" |
| 429 | serviceKind := "Result" |
| 430 | if req { |
| 431 | msgKind = "Request" |
| 432 | serviceKind = "Payload" |
| 433 | } |
| 434 | if isEmpty(serviceAtt) { |
| 435 | verr.Add(e, "%s message is defined but %s is not defined in method", msgKind, serviceKind) |
| 436 | return verr |
| 437 | } |
| 438 | |
| 439 | if !IsObject(serviceAtt.Type) { |
| 440 | // service type (payload or result) is a primitive, array, or map |
| 441 | // The message type must have at most one field and that field must be |
| 442 | // of the same type as the service type. |
| 443 | msgObj := AsObject(msgAtt.Type) |
| 444 | if flen := len(*msgObj); flen != 1 { |
| 445 | verr.Add(e, "%s is not an object type. %s message should have at most 1 field. Got %d.", serviceKind, msgKind, flen) |
| 446 | } else { |
| 447 | for _, f := range *msgObj { |
| 448 | if f.Attribute.Type != serviceAtt.Type { |
| 449 | verr.Add(e, "%s message field %q is %q type but the %s type is %q.", msgKind, f.Name, f.Attribute.Type.Name(), serviceKind, serviceAtt.Type.Name()) |
| 450 | } |
| 451 | } |
| 452 | } |
| 453 | } else { |
| 454 | // service type is an object. Verify the attributes defined in the |
| 455 | // message are found in the service type. |
| 456 | // msgFields will contain the attributes from the service type that has the |
| 457 | // same name as the message attributes so that we can validate the |
| 458 | // rpc:tag in the meta. |
| 459 | msgFields := &Object{} |
| 460 | for _, nat := range *AsObject(msgAtt.Type) { |
| 461 | if a := serviceAtt.Find(nat.Name); a != nil { |
| 462 | msgFields.Set(nat.Name, a) |
| 463 | break |
| 464 | } |
| 465 | verr.Add(e, "%s message attribute %q is not found in %s", msgKind, nat.Name, serviceKind) |
| 466 | } |
| 467 | // validate rpc:tag in meta for the message fields |
| 468 | verr.Merge(validateRPCTags(msgFields, e)) |
| 469 | } |
| 470 | return verr |
| 471 | } |
| 472 | |
| 473 | // validateRPCTags verifies whether every attribute in the object type has |
| 474 | // "rpc:tag" set in the meta and the tag numbers are unique. |