package impl
import (
)
type MessageInfo struct {
GoReflectType reflect.Type
Desc protoreflect.MessageDescriptor
Exporter exporter
OneofWrappers []interface{}
initMu sync.Mutex
initDone uint32
reflectMessageInfo
coderMessageInfo
}
type exporter func(v interface{}, i int) interface{}
func ( reflect.Type) *MessageInfo {
, := reflect.Zero().Interface().(protoreflect.ProtoMessage)
if ! {
return nil
}
, := .ProtoReflect().(interface{ () *MessageInfo })
if ! {
return nil
}
return .()
}
func ( *MessageInfo) () {
if atomic.LoadUint32(&.initDone) == 0 {
.initOnce()
}
}
func ( *MessageInfo) () {
.initMu.Lock()
defer .initMu.Unlock()
if .initDone == 1 {
return
}
:= .GoReflectType
if .Kind() != reflect.Ptr && .Elem().Kind() != reflect.Struct {
panic(fmt.Sprintf("got %v, want *struct kind", ))
}
= .Elem()
:= .makeStructInfo()
.makeReflectFuncs(, )
.makeCoderMethods(, )
atomic.StoreUint32(&.initDone, 1)
}
func ( *MessageInfo) ( protoreflect.Message) ( pointer, bool) {
switch m := .(type) {
case *messageState:
return .pointer(), .messageInfo() ==
case *messageReflectWrapper:
return .pointer(), .messageInfo() ==
}
return pointer{}, false
}
type (
SizeCache = int32
WeakFields = map[int32]protoreflect.ProtoMessage
UnknownFields = unknownFieldsA
unknownFieldsA = []byte
unknownFieldsB = *[]byte
ExtensionFields = map[int32]ExtensionField
)
var (
sizecacheType = reflect.TypeOf(SizeCache(0))
weakFieldsType = reflect.TypeOf(WeakFields(nil))
unknownFieldsAType = reflect.TypeOf(unknownFieldsA(nil))
unknownFieldsBType = reflect.TypeOf(unknownFieldsB(nil))
extensionFieldsType = reflect.TypeOf(ExtensionFields(nil))
)
type structInfo struct {
sizecacheOffset offset
sizecacheType reflect.Type
weakOffset offset
weakType reflect.Type
unknownOffset offset
unknownType reflect.Type
extensionOffset offset
extensionType reflect.Type
fieldsByNumber map[protoreflect.FieldNumber]reflect.StructField
oneofsByName map[protoreflect.Name]reflect.StructField
oneofWrappersByType map[reflect.Type]protoreflect.FieldNumber
oneofWrappersByNumber map[protoreflect.FieldNumber]reflect.Type
}
func ( *MessageInfo) ( reflect.Type) structInfo {
:= structInfo{
sizecacheOffset: invalidOffset,
weakOffset: invalidOffset,
unknownOffset: invalidOffset,
extensionOffset: invalidOffset,
fieldsByNumber: map[protoreflect.FieldNumber]reflect.StructField{},
oneofsByName: map[protoreflect.Name]reflect.StructField{},
oneofWrappersByType: map[reflect.Type]protoreflect.FieldNumber{},
oneofWrappersByNumber: map[protoreflect.FieldNumber]reflect.Type{},
}
:
for := 0; < .NumField(); ++ {
switch := .Field(); .Name {
case genid.SizeCache_goname, genid.SizeCacheA_goname:
if .Type == sizecacheType {
.sizecacheOffset = offsetOf(, .Exporter)
.sizecacheType = .Type
}
case genid.WeakFields_goname, genid.WeakFieldsA_goname:
if .Type == weakFieldsType {
.weakOffset = offsetOf(, .Exporter)
.weakType = .Type
}
case genid.UnknownFields_goname, genid.UnknownFieldsA_goname:
if .Type == unknownFieldsAType || .Type == unknownFieldsBType {
.unknownOffset = offsetOf(, .Exporter)
.unknownType = .Type
}
case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname:
if .Type == extensionFieldsType {
.extensionOffset = offsetOf(, .Exporter)
.extensionType = .Type
}
default:
for , := range strings.Split(.Tag.Get("protobuf"), ",") {
if len() > 0 && strings.Trim(, "0123456789") == "" {
, := strconv.ParseUint(, 10, 64)
.fieldsByNumber[protoreflect.FieldNumber()] =
continue
}
}
if := .Tag.Get("protobuf_oneof"); len() > 0 {
.oneofsByName[protoreflect.Name()] =
continue
}
}
}
:= .OneofWrappers
for , := range []string{"XXX_OneofFuncs", "XXX_OneofWrappers"} {
if , := reflect.PtrTo().MethodByName(); {
for , := range .Func.Call([]reflect.Value{reflect.Zero(.Type.In(0))}) {
if , := .Interface().([]interface{}); {
=
}
}
}
}
for , := range {
:= reflect.TypeOf().Elem()
:= .Field(0)
for , := range strings.Split(.Tag.Get("protobuf"), ",") {
if len() > 0 && strings.Trim(, "0123456789") == "" {
, := strconv.ParseUint(, 10, 64)
.oneofWrappersByType[] = protoreflect.FieldNumber()
.oneofWrappersByNumber[protoreflect.FieldNumber()] =
break
}
}
}
return
}
func ( *MessageInfo) () protoreflect.Message {
:= reflect.New(.GoReflectType.Elem()).Interface()
if , := .(protoreflect.ProtoMessage); {
return .ProtoReflect()
}
return .MessageOf()
}
func ( *MessageInfo) () protoreflect.Message {
return .MessageOf(reflect.Zero(.GoReflectType).Interface())
}
func ( *MessageInfo) () protoreflect.MessageDescriptor {
return .Desc
}
func ( *MessageInfo) ( int) protoreflect.EnumType {
.init()
:= .Desc.Fields().Get()
return Export{}.EnumTypeOf(.fieldTypes[.Number()])
}
func ( *MessageInfo) ( int) protoreflect.MessageType {
.init()
:= .Desc.Fields().Get()
switch {
case .IsWeak():
, := protoregistry.GlobalTypes.FindMessageByName(.Message().FullName())
return
case .IsMap():
return mapEntryType{.Message(), .fieldTypes[.Number()]}
default:
return Export{}.MessageTypeOf(.fieldTypes[.Number()])
}
}
type mapEntryType struct {
desc protoreflect.MessageDescriptor
valType interface{}
}
func ( mapEntryType) () protoreflect.Message {
return nil
}
func ( mapEntryType) () protoreflect.Message {
return nil
}
func ( mapEntryType) () protoreflect.MessageDescriptor {
return .desc
}
func ( mapEntryType) ( int) protoreflect.EnumType {
:= .desc.Fields().Get()
if .Enum() == nil {
return nil
}
return Export{}.EnumTypeOf(.valType)
}
func ( mapEntryType) ( int) protoreflect.MessageType {
:= .desc.Fields().Get()
if .Message() == nil {
return nil
}
return Export{}.MessageTypeOf(.valType)
}