package impl
import (
)
type fieldInfo struct {
fieldDesc protoreflect.FieldDescriptor
has func(pointer) bool
clear func(pointer)
get func(pointer) protoreflect.Value
set func(pointer, protoreflect.Value)
mutable func(pointer) protoreflect.Value
newMessage func() protoreflect.Message
newField func() protoreflect.Value
}
func ( protoreflect.FieldDescriptor) fieldInfo {
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
return false
},
clear: func( pointer) {
panic("missing Go struct field for " + string(.FullName()))
},
get: func( pointer) protoreflect.Value {
return .Default()
},
set: func( pointer, protoreflect.Value) {
panic("missing Go struct field for " + string(.FullName()))
},
mutable: func( pointer) protoreflect.Value {
panic("missing Go struct field for " + string(.FullName()))
},
newMessage: func() protoreflect.Message {
panic("missing Go struct field for " + string(.FullName()))
},
newField: func() protoreflect.Value {
if := .Default(); .IsValid() {
return
}
panic("missing Go struct field for " + string(.FullName()))
},
}
}
func ( protoreflect.FieldDescriptor, reflect.StructField, exporter, reflect.Type) fieldInfo {
:= .Type
if .Kind() != reflect.Interface {
panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", .FullName(), ))
}
if .Kind() != reflect.Struct {
panic(fmt.Sprintf("field %v has invalid type: got %v, want struct kind", .FullName(), ))
}
if !reflect.PtrTo().Implements() {
panic(fmt.Sprintf("field %v has invalid type: %v does not implement %v", .FullName(), , ))
}
:= NewConverter(.Field(0).Type, )
:= .Message() != nil
:= offsetOf(, )
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() || .Elem().Type().Elem() != || .Elem().IsNil() {
return false
}
return true
},
clear: func( pointer) {
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() || .Elem().Type().Elem() != {
return
}
.Set(reflect.Zero(.Type()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() || .Elem().Type().Elem() != || .Elem().IsNil() {
return .Zero()
}
= .Elem().Elem().Field(0)
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() || .Elem().Type().Elem() != || .Elem().IsNil() {
.Set(reflect.New())
}
= .Elem().Elem().Field(0)
.Set(.GoValueOf())
},
mutable: func( pointer) protoreflect.Value {
if ! {
panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", .FullName()))
}
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() || .Elem().Type().Elem() != || .Elem().IsNil() {
.Set(reflect.New())
}
= .Elem().Elem().Field(0)
if .Kind() == reflect.Ptr && .IsNil() {
.Set(.GoValueOf(protoreflect.ValueOfMessage(.New().Message())))
}
return .PBValueOf()
},
newMessage: func() protoreflect.Message {
return .New().Message()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( protoreflect.FieldDescriptor, reflect.StructField, exporter) fieldInfo {
:= .Type
if .Kind() != reflect.Map {
panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", .FullName(), ))
}
:= NewConverter(, )
:= offsetOf(, )
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AsValueOf(.Type).Elem()
return .Len() > 0
},
clear: func( pointer) {
:= .Apply().AsValueOf(.Type).Elem()
.Set(reflect.Zero(.Type()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AsValueOf(.Type).Elem()
if .Len() == 0 {
return .Zero()
}
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .Apply().AsValueOf(.Type).Elem()
:= .GoValueOf()
if .IsNil() {
panic(fmt.Sprintf("map field %v cannot be set with read-only value", .FullName()))
}
.Set()
},
mutable: func( pointer) protoreflect.Value {
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() {
.Set(reflect.MakeMap(.Type))
}
return .PBValueOf()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( protoreflect.FieldDescriptor, reflect.StructField, exporter) fieldInfo {
:= .Type
if .Kind() != reflect.Slice {
panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", .FullName(), ))
}
:= NewConverter(reflect.PtrTo(), )
:= offsetOf(, )
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AsValueOf(.Type).Elem()
return .Len() > 0
},
clear: func( pointer) {
:= .Apply().AsValueOf(.Type).Elem()
.Set(reflect.Zero(.Type()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AsValueOf(.Type)
if .Elem().Len() == 0 {
return .Zero()
}
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .Apply().AsValueOf(.Type).Elem()
:= .GoValueOf()
if .IsNil() {
panic(fmt.Sprintf("list field %v cannot be set with read-only value", .FullName()))
}
.Set(.Elem())
},
mutable: func( pointer) protoreflect.Value {
:= .Apply().AsValueOf(.Type)
return .PBValueOf()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
var (
nilBytes = reflect.ValueOf([]byte(nil))
emptyBytes = reflect.ValueOf([]byte{})
)
func ( protoreflect.FieldDescriptor, reflect.StructField, exporter) fieldInfo {
:= .Type
:= .HasPresence()
:= .Kind() == reflect.Slice && .Elem().Kind() == reflect.Uint8
if {
if .Kind() != reflect.Ptr && .Kind() != reflect.Slice {
= false
}
if .Kind() == reflect.Ptr {
= .Elem()
}
}
:= NewConverter(, )
:= offsetOf(, )
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AsValueOf(.Type).Elem()
if {
return !.IsNil()
}
switch .Kind() {
case reflect.Bool:
return .Bool()
case reflect.Int32, reflect.Int64:
return .Int() != 0
case reflect.Uint32, reflect.Uint64:
return .Uint() != 0
case reflect.Float32, reflect.Float64:
return .Float() != 0 || math.Signbit(.Float())
case reflect.String, reflect.Slice:
return .Len() > 0
default:
panic(fmt.Sprintf("field %v has invalid type: %v", .FullName(), .Type()))
}
},
clear: func( pointer) {
:= .Apply().AsValueOf(.Type).Elem()
.Set(reflect.Zero(.Type()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AsValueOf(.Type).Elem()
if {
if .IsNil() {
return .Zero()
}
if .Kind() == reflect.Ptr {
= .Elem()
}
}
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .Apply().AsValueOf(.Type).Elem()
if && .Kind() == reflect.Ptr {
if .IsNil() {
.Set(reflect.New())
}
= .Elem()
}
.Set(.GoValueOf())
if && .Len() == 0 {
if {
.Set(emptyBytes)
} else {
.Set(nilBytes)
}
}
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( protoreflect.FieldDescriptor, offset) fieldInfo {
if !flags.ProtoLegacy {
panic("no support for proto1 weak fields")
}
var sync.Once
var protoreflect.MessageType
:= func() {
.Do(func() {
:= .Message().FullName()
, _ = protoregistry.GlobalTypes.FindMessageByName()
if == nil {
panic(fmt.Sprintf("weak message %v for field %v is not linked in", , .FullName()))
}
})
}
:= .Number()
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
, := .Apply().WeakFields().get()
return
},
clear: func( pointer) {
.Apply().WeakFields().clear()
},
get: func( pointer) protoreflect.Value {
()
if .IsNil() {
return protoreflect.ValueOfMessage(.Zero())
}
, := .Apply().WeakFields().get()
if ! {
return protoreflect.ValueOfMessage(.Zero())
}
return protoreflect.ValueOfMessage(.ProtoReflect())
},
set: func( pointer, protoreflect.Value) {
()
:= .Message()
if .Descriptor() != .Descriptor() {
if , := .Descriptor().FullName(), .Descriptor().FullName(); != {
panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", .FullName(), , ))
}
panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", .FullName(), .Descriptor().FullName()))
}
.Apply().WeakFields().set(, .Interface())
},
mutable: func( pointer) protoreflect.Value {
()
:= .Apply().WeakFields()
, := .get()
if ! {
= .New().Interface()
.set(, )
}
return protoreflect.ValueOfMessage(.ProtoReflect())
},
newMessage: func() protoreflect.Message {
()
return .New()
},
newField: func() protoreflect.Value {
()
return protoreflect.ValueOfMessage(.New())
},
}
}
func ( protoreflect.FieldDescriptor, reflect.StructField, exporter) fieldInfo {
:= .Type
:= NewConverter(, )
:= offsetOf(, )
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AsValueOf(.Type).Elem()
if .Type.Kind() != reflect.Ptr {
return !isZero()
}
return !.IsNil()
},
clear: func( pointer) {
:= .Apply().AsValueOf(.Type).Elem()
.Set(reflect.Zero(.Type()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AsValueOf(.Type).Elem()
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .Apply().AsValueOf(.Type).Elem()
.Set(.GoValueOf())
if .Type.Kind() == reflect.Ptr && .IsNil() {
panic(fmt.Sprintf("field %v has invalid nil pointer", .FullName()))
}
},
mutable: func( pointer) protoreflect.Value {
:= .Apply().AsValueOf(.Type).Elem()
if .Type.Kind() == reflect.Ptr && .IsNil() {
.Set(.GoValueOf(.New()))
}
return .PBValueOf()
},
newMessage: func() protoreflect.Message {
return .New().Message()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
type oneofInfo struct {
oneofDesc protoreflect.OneofDescriptor
which func(pointer) protoreflect.FieldNumber
}
func ( protoreflect.OneofDescriptor, structInfo, exporter) *oneofInfo {
:= &oneofInfo{oneofDesc: }
if .IsSynthetic() {
:= .fieldsByNumber[.Fields().Get(0).Number()]
:= offsetOf(, )
.which = func( pointer) protoreflect.FieldNumber {
if .IsNil() {
return 0
}
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() {
return 0
}
return .Fields().Get(0).Number()
}
} else {
:= .oneofsByName[.Name()]
:= offsetOf(, )
.which = func( pointer) protoreflect.FieldNumber {
if .IsNil() {
return 0
}
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() {
return 0
}
= .Elem()
if .IsNil() {
return 0
}
return .oneofWrappersByType[.Type().Elem()]
}
}
return
}
func ( reflect.Value) bool {
switch .Kind() {
case reflect.Bool:
return !.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return .Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return .Uint() == 0
case reflect.Float32, reflect.Float64:
return math.Float64bits(.Float()) == 0
case reflect.Complex64, reflect.Complex128:
:= .Complex()
return math.Float64bits(real()) == 0 && math.Float64bits(imag()) == 0
case reflect.Array:
for := 0; < .Len(); ++ {
if !(.Index()) {
return false
}
}
return true
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
return .IsNil()
case reflect.String:
return .Len() == 0
case reflect.Struct:
for := 0; < .NumField(); ++ {
if !(.Field()) {
return false
}
}
return true
default:
panic(&reflect.ValueError{"reflect.Value.IsZero", .Kind()})
}
}