(e ast.Expr)
| 480 | } |
| 481 | |
| 482 | func (c *checker) checkCreateStruct(e ast.Expr) { |
| 483 | msgVal := e.AsStruct() |
| 484 | // Determine the type of the message. |
| 485 | resultType := types.ErrorType |
| 486 | ident := c.env.resolveTypeIdent(msgVal.TypeName()) |
| 487 | if ident == nil { |
| 488 | c.errors.undeclaredReference( |
| 489 | e.ID(), c.location(e), c.env.container.Name(), msgVal.TypeName()) |
| 490 | c.setType(e, types.ErrorType) |
| 491 | return |
| 492 | } |
| 493 | // Ensure the type name is fully qualified in the AST. |
| 494 | typeName := ident.Name() |
| 495 | if msgVal.TypeName() != typeName { |
| 496 | e.SetKindCase(c.NewStruct(e.ID(), typeName, msgVal.Fields())) |
| 497 | msgVal = e.AsStruct() |
| 498 | } |
| 499 | c.setReference(e, ast.NewIdentReference(typeName, nil)) |
| 500 | identKind := ident.Type().Kind() |
| 501 | if identKind != types.ErrorKind { |
| 502 | if identKind != types.TypeKind { |
| 503 | c.errors.notAType(e.ID(), c.location(e), ident.Type().DeclaredTypeName()) |
| 504 | } else { |
| 505 | resultType = ident.Type().Parameters()[0] |
| 506 | // Backwards compatibility test between well-known types and message types |
| 507 | // In this context, the type is being instantiated by its protobuf name which |
| 508 | // is not ideal or recommended, but some users expect this to work. |
| 509 | if isWellKnownType(resultType) { |
| 510 | typeName = getWellKnownTypeName(resultType) |
| 511 | } else if resultType.Kind() == types.StructKind { |
| 512 | typeName = resultType.DeclaredTypeName() |
| 513 | } else { |
| 514 | c.errors.notAMessageType(e.ID(), c.location(e), resultType.DeclaredTypeName()) |
| 515 | resultType = types.ErrorType |
| 516 | } |
| 517 | } |
| 518 | } |
| 519 | c.setType(e, resultType) |
| 520 | |
| 521 | // Check the field initializers. |
| 522 | for _, f := range msgVal.Fields() { |
| 523 | field := f.AsStructField() |
| 524 | fieldName := field.Name() |
| 525 | value := field.Value() |
| 526 | c.check(value) |
| 527 | |
| 528 | fieldType := types.ErrorType |
| 529 | ft, found := c.lookupFieldType(f.ID(), typeName, fieldName) |
| 530 | if found { |
| 531 | fieldType = ft |
| 532 | } |
| 533 | |
| 534 | valType := c.getType(value) |
| 535 | if field.IsOptional() { |
| 536 | var isOptional bool |
| 537 | valType, isOptional = maybeUnwrapOptional(valType) |
| 538 | if !isOptional && !isDyn(valType) { |
| 539 | c.errors.typeMismatch(value.ID(), c.location(value), types.NewOptionalType(valType), valType) |
no test coverage detected