package impl
import (
)
type coderMessageInfo struct {
methods protoiface.Methods
orderedCoderFields []*coderFieldInfo
denseCoderFields []*coderFieldInfo
coderFields map[protowire.Number]*coderFieldInfo
sizecacheOffset offset
unknownOffset offset
unknownPtrKind bool
extensionOffset offset
needsInitCheck bool
isMessageSet bool
numRequiredFields uint8
}
type coderFieldInfo struct {
funcs pointerCoderFuncs
mi *MessageInfo
ft reflect.Type
validation validationInfo
num protoreflect.FieldNumber
offset offset
wiretag uint64
tagsize int
isPointer bool
isRequired bool
}
func ( *MessageInfo) ( reflect.Type, structInfo) {
.sizecacheOffset = invalidOffset
.unknownOffset = invalidOffset
.extensionOffset = invalidOffset
if .sizecacheOffset.IsValid() && .sizecacheType == sizecacheType {
.sizecacheOffset = .sizecacheOffset
}
if .unknownOffset.IsValid() && (.unknownType == unknownFieldsAType || .unknownType == unknownFieldsBType) {
.unknownOffset = .unknownOffset
.unknownPtrKind = .unknownType.Kind() == reflect.Ptr
}
if .extensionOffset.IsValid() && .extensionType == extensionFieldsType {
.extensionOffset = .extensionOffset
}
.coderFields = make(map[protowire.Number]*coderFieldInfo)
:= .Desc.Fields()
:= make([]coderFieldInfo, .Len())
for := 0; < .Len(); ++ {
:= .Get()
:= .fieldsByNumber[.Number()]
:= .ContainingOneof() != nil && !.ContainingOneof().IsSynthetic()
if {
= .oneofsByName[.ContainingOneof().Name()]
}
:= .Type
var uint64
if !.IsPacked() {
= protowire.EncodeTag(.Number(), wireTypes[.Kind()])
} else {
= protowire.EncodeTag(.Number(), protowire.BytesType)
}
var offset
var pointerCoderFuncs
var *MessageInfo
switch {
case == nil:
= pointerCoderFuncs{
size: func( pointer, *coderFieldInfo, marshalOptions) int {
return 0
},
marshal: func( []byte, pointer, *coderFieldInfo, marshalOptions) ([]byte, error) {
return nil, nil
},
unmarshal: func( []byte, pointer, protowire.Type, *coderFieldInfo, unmarshalOptions) (unmarshalOutput, error) {
panic("missing Go struct field for " + string(.FullName()))
},
isInit: func( pointer, *coderFieldInfo) error {
panic("missing Go struct field for " + string(.FullName()))
},
merge: func(, pointer, *coderFieldInfo, mergeOptions) {
panic("missing Go struct field for " + string(.FullName()))
},
}
case :
= offsetOf(, .Exporter)
case .IsWeak():
= .weakOffset
= makeWeakMessageFieldCoder()
default:
= offsetOf(, .Exporter)
, = fieldCoder(, )
}
:= &[]
* = coderFieldInfo{
num: .Number(),
offset: ,
wiretag: ,
ft: ,
tagsize: protowire.SizeVarint(),
funcs: ,
mi: ,
validation: newFieldValidationInfo(, , , ),
isPointer: .Cardinality() == protoreflect.Repeated || .HasPresence(),
isRequired: .Cardinality() == protoreflect.Required,
}
.orderedCoderFields = append(.orderedCoderFields, )
.coderFields[.num] =
}
for , := 0, .Desc.Oneofs(); < .Len(); ++ {
if := .Get(); !.IsSynthetic() {
.initOneofFieldCoders(, )
}
}
if messageset.IsMessageSet(.Desc) {
if !.extensionOffset.IsValid() {
panic(fmt.Sprintf("%v: MessageSet with no extensions field", .Desc.FullName()))
}
if !.unknownOffset.IsValid() {
panic(fmt.Sprintf("%v: MessageSet with no unknown field", .Desc.FullName()))
}
.isMessageSet = true
}
sort.Slice(.orderedCoderFields, func(, int) bool {
return .orderedCoderFields[].num < .orderedCoderFields[].num
})
var protoreflect.FieldNumber
for , := range .orderedCoderFields {
if .num >= 16 && .num >= 2* {
break
}
= .num
}
.denseCoderFields = make([]*coderFieldInfo, +1)
for , := range .orderedCoderFields {
if int(.num) >= len(.denseCoderFields) {
break
}
.denseCoderFields[.num] =
}
if .Desc.Oneofs().Len() > 0 {
sort.Slice(.orderedCoderFields, func(, int) bool {
:= .ByNumber(.orderedCoderFields[].num)
:= .ByNumber(.orderedCoderFields[].num)
return order.LegacyFieldOrder(, )
})
}
.needsInitCheck = needsInitCheck(.Desc)
if .methods.Marshal == nil && .methods.Size == nil {
.methods.Flags |= protoiface.SupportMarshalDeterministic
.methods.Marshal = .marshal
.methods.Size = .size
}
if .methods.Unmarshal == nil {
.methods.Flags |= protoiface.SupportUnmarshalDiscardUnknown
.methods.Unmarshal = .unmarshal
}
if .methods.CheckInitialized == nil {
.methods.CheckInitialized = .checkInitialized
}
if .methods.Merge == nil {
.methods.Merge = .merge
}
}
func ( *MessageInfo) ( pointer) *[]byte {
if .unknownPtrKind {
return *.Apply(.unknownOffset).BytesPtr()
} else {
return .Apply(.unknownOffset).Bytes()
}
}
func ( *MessageInfo) ( pointer) *[]byte {
if .unknownPtrKind {
:= .Apply(.unknownOffset).BytesPtr()
if * == nil {
* = new([]byte)
}
return *
} else {
return .Apply(.unknownOffset).Bytes()
}
}