mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 06:54:01 +00:00
Support protobuf.as=Message for aliasing
In order to allow a Go type to have a different internal representation, provide the comment `// +protobuf.as=MESSAGENAME` which substitutes the current message's members with the named message's members. Used by the unversioned.Time type to have the same fields as unversioned.Timestamp and to have an alternate serialization.
This commit is contained in:
parent
fd1923098b
commit
529bd2bf98
@ -135,8 +135,9 @@ func (g *genProtoIDL) GenerateType(c *generator.Context, t *types.Type, w io.Wri
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
b := bodyGen{
|
||||
locator: &protobufLocator{
|
||||
namer: c.Namers["proto"].(ProtobufFromGoNamer),
|
||||
tracker: g.imports,
|
||||
namer: c.Namers["proto"].(ProtobufFromGoNamer),
|
||||
tracker: g.imports,
|
||||
universe: c.Universe,
|
||||
|
||||
localGoPackage: g.localGoPackage.Package,
|
||||
},
|
||||
@ -164,12 +165,14 @@ type ProtobufFromGoNamer interface {
|
||||
|
||||
type ProtobufLocator interface {
|
||||
ProtoTypeFor(t *types.Type) (*types.Type, error)
|
||||
GoTypeForName(name types.Name) *types.Type
|
||||
CastTypeName(name types.Name) string
|
||||
}
|
||||
|
||||
type protobufLocator struct {
|
||||
namer ProtobufFromGoNamer
|
||||
tracker namer.ImportTracker
|
||||
namer ProtobufFromGoNamer
|
||||
tracker namer.ImportTracker
|
||||
universe types.Universe
|
||||
|
||||
localGoPackage string
|
||||
}
|
||||
@ -183,6 +186,13 @@ func (p protobufLocator) CastTypeName(name types.Name) string {
|
||||
return name.String()
|
||||
}
|
||||
|
||||
func (p protobufLocator) GoTypeForName(name types.Name) *types.Type {
|
||||
if len(name.Package) == 0 {
|
||||
name.Package = p.localGoPackage
|
||||
}
|
||||
return p.universe.Type(name)
|
||||
}
|
||||
|
||||
// ProtoTypeFor locates a Protobuf type for the provided Go type (if possible).
|
||||
func (p protobufLocator) ProtoTypeFor(t *types.Type) (*types.Type, error) {
|
||||
switch {
|
||||
@ -231,6 +241,7 @@ func (b bodyGen) doStruct(sw *generator.SnippetWriter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var alias *types.Type
|
||||
var fields []protoField
|
||||
options := []string{}
|
||||
allOptions := types.ExtractCommentTags("+", b.t.CommentLines)
|
||||
@ -254,6 +265,14 @@ func (b bodyGen) doStruct(sw *generator.SnippetWriter) error {
|
||||
options = append(options, fmt.Sprintf("%s = %s", key, v))
|
||||
}
|
||||
}
|
||||
// protobuf.as allows a type to have the same message contents as another Go type
|
||||
case k == "protobuf.as":
|
||||
fields = nil
|
||||
if alias = b.locator.GoTypeForName(types.Name{Name: v}); alias == nil {
|
||||
return fmt.Errorf("type %v references alias %q which does not exist", b.t, v)
|
||||
}
|
||||
// protobuf.embed instructs the generator to use the named type in this package
|
||||
// as an embedded message.
|
||||
case k == "protobuf.embed":
|
||||
fields = []protoField{
|
||||
{
|
||||
@ -270,10 +289,13 @@ func (b bodyGen) doStruct(sw *generator.SnippetWriter) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
if alias == nil {
|
||||
alias = b.t
|
||||
}
|
||||
|
||||
// If we don't explicitly embed anything, generate fields by traversing fields.
|
||||
if fields == nil {
|
||||
memberFields, err := membersToFields(b.locator, b.t, b.localPackage, b.omitFieldTypes)
|
||||
memberFields, err := membersToFields(b.locator, alias, b.localPackage, b.omitFieldTypes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("type %v cannot be converted to protobuf: %v", b.t, err)
|
||||
}
|
||||
@ -454,7 +476,7 @@ func memberTypeToProtobufField(locator ProtobufLocator, field *protoField, t *ty
|
||||
|
||||
// protobufTagToField extracts information from an existing protobuf tag
|
||||
func protobufTagToField(tag string, field *protoField, m types.Member, t *types.Type, localPackage types.Name) error {
|
||||
if len(tag) == 0 {
|
||||
if len(tag) == 0 || tag == "-" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,11 @@ func assignGoTypeToProtoPackage(p *protobufPackage, t *types.Type, local, global
|
||||
continue
|
||||
}
|
||||
field := &protoField{}
|
||||
if err := protobufTagToField(reflect.StructTag(m.Tags).Get("protobuf"), field, m, t, p.ProtoTypeName()); err == nil && field.Type != nil {
|
||||
tag := reflect.StructTag(m.Tags).Get("protobuf")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
if err := protobufTagToField(tag, field, m, t, p.ProtoTypeName()); err == nil && field.Type != nil {
|
||||
assignGoTypeToProtoPackage(p, field.Type, local, global)
|
||||
continue
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user