github.com/cosmos/cosmos-proto@v1.0.0-beta.3/features/fastreflection/clear.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  // fields are not populated if
    10  // if scalar: value != zero value
    11  // if msg value != nil
    12  // if list len(list) != 0
    13  // if map len(map) != 0
    14  // if oneof: oneof != nil (if oneof is scalar do we need to check it??)
    15  // if bytes: len(bytes) != 0
    16  type clearGen struct {
    17  	*generator.GeneratedFile
    18  	typeName string
    19  	message  *protogen.Message
    20  }
    21  
    22  func (g *clearGen) genComments() {
    23  	g.P("// Clear clears the field such that a subsequent Has call reports false.")
    24  	g.P("//")
    25  	g.P("// Clearing an extension field clears both the extension type and value")
    26  	g.P("// associated with the given field number.")
    27  	g.P("//")
    28  	g.P("// Clear is a mutating operation and unsafe for concurrent use.")
    29  }
    30  
    31  func (g *clearGen) generate() {
    32  	g.genComments()
    33  	g.P("func (x *", g.typeName, ") Clear(fd ", protoreflectPkg.Ident("FieldDescriptor"), ") {")
    34  	g.P("switch fd.FullName() {")
    35  	for _, field := range g.message.Fields {
    36  		g.genField(field)
    37  	}
    38  	g.P("default:")
    39  	g.P("if fd.IsExtension() {")
    40  	g.P("panic(", fmtPkg.Ident("Errorf"), "(\"proto3 declared messages do not support extensions: ", g.message.Desc.FullName(), "\"))")
    41  	g.P("}")
    42  	g.P("panic(fmt.Errorf(\"message ", g.message.Desc.FullName(), " does not contain field %s\", fd.FullName()))")
    43  	g.P("}")
    44  	g.P("}")
    45  }
    46  
    47  func (g *clearGen) genField(field *protogen.Field) {
    48  	g.P("case \"", field.Desc.FullName(), "\":")
    49  	if field.Desc.HasPresence() || field.Desc.IsList() || field.Desc.IsMap() || field.Desc.Kind() == protoreflect.BytesKind {
    50  		g.genNullable(field)
    51  		return
    52  	}
    53  
    54  	g.P("x.", field.GoName, " = ", zeroValueForField(nil, field))
    55  }
    56  
    57  func (g *clearGen) genNullable(field *protogen.Field) {
    58  	switch {
    59  	case field.Desc.ContainingOneof() != nil:
    60  		g.P("x.", field.Oneof.GoName, " = nil")
    61  	case field.Desc.IsMap(), field.Desc.IsList(), field.Desc.Kind() == protoreflect.BytesKind:
    62  		g.P("x.", field.GoName, " = nil")
    63  	case field.Desc.Kind() == protoreflect.MessageKind:
    64  		g.P(" x.", field.GoName, " = nil")
    65  	default:
    66  		panic("unknown case")
    67  	}
    68  }