github.com/cosmos/cosmos-proto@v1.0.0-beta.3/features/fastreflection/new_field.go (about)

     1  package fastreflection
     2  
     3  import (
     4  	"github.com/cosmos/cosmos-proto/generator"
     5  	"google.golang.org/protobuf/compiler/protogen"
     6  	"google.golang.org/protobuf/reflect/protoreflect"
     7  )
     8  
     9  type newFieldGen struct {
    10  	*generator.GeneratedFile
    11  	typeName string
    12  	message  *protogen.Message
    13  }
    14  
    15  func (g *newFieldGen) generate() {
    16  	g.genComment()
    17  	g.P("func (x *", g.typeName, ") NewField(fd ", protoreflectPkg.Ident("FieldDescriptor"), ") ", protoreflectPkg.Ident("Value"), " {")
    18  	g.P("switch fd.FullName() {")
    19  	for _, field := range g.message.Fields {
    20  		g.P("case \"", field.Desc.FullName(), "\":")
    21  		g.genField(field)
    22  	}
    23  	g.P("default: ")
    24  	g.P("if fd.IsExtension() {")
    25  	g.P("panic(", fmtPkg.Ident("Errorf"), "(\"proto3 declared messages do not support extensions: ", g.message.Desc.FullName(), "\"))")
    26  	g.P("}")
    27  	g.P("panic(fmt.Errorf(\"message ", g.message.Desc.FullName(), " does not contain field %s\", fd.FullName()))")
    28  	g.P("}")
    29  	g.P("}")
    30  }
    31  
    32  func (g *newFieldGen) genComment() {
    33  	g.P("// NewField returns a new value that is assignable to the field")
    34  	g.P("// for the given descriptor. For scalars, this returns the default value.")
    35  	g.P("// For lists, maps, and messages, this returns a new, empty, mutable value.")
    36  }
    37  
    38  func (g *newFieldGen) genField(field *protogen.Field) {
    39  	switch {
    40  	case field.Desc.IsMap(), field.Desc.IsList(), field.Desc.Kind() == protoreflect.MessageKind:
    41  		g.genMutable(field)
    42  	default:
    43  		g.P("return ", kindToValueConstructor(field.Desc.Kind()), "(", zeroValueForField(g.GeneratedFile, field), ")")
    44  	}
    45  }
    46  
    47  func (g *newFieldGen) genMutable(field *protogen.Field) {
    48  	switch {
    49  	case field.Oneof != nil:
    50  		g.genOneof(field)
    51  	case field.Desc.IsMap():
    52  		g.P("m := make(map[", getGoType(g.GeneratedFile, field.Message.Fields[0]), "]", getGoType(g.GeneratedFile, field.Message.Fields[1]), ")")
    53  		g.P("return ", protoreflectPkg.Ident("ValueOfMap"), "(&", mapTypeName(field), "{m: &m})")
    54  	case field.Desc.IsList():
    55  		g.P("list := []", getGoType(g.GeneratedFile, field), "{}")
    56  		g.P("return ", protoreflectPkg.Ident("ValueOfList"), "(&", listTypeName(field), "{list: &list})")
    57  	case field.Desc.Kind() == protoreflect.MessageKind:
    58  		g.P("m := new(", g.QualifiedGoIdent(field.Message.GoIdent), ")")
    59  		g.P("return ", protoreflectPkg.Ident("ValueOfMessage"), "(m.ProtoReflect())")
    60  	default:
    61  		panic("unreachable")
    62  	}
    63  }
    64  
    65  func (g *newFieldGen) genOneof(field *protogen.Field) {
    66  	if field.Desc.Kind() != protoreflect.MessageKind {
    67  		panic("newfield oneof fastGenerator should be applied only to mutable message types")
    68  	}
    69  	g.P("value := &", g.QualifiedGoIdent(field.Message.GoIdent), "{}")
    70  	g.P("return ", protoreflectPkg.Ident("ValueOfMessage"), "(value.ProtoReflect())")
    71  }