type coderMessageInfo struct {
methods piface .Methods
orderedCoderFields []*coderFieldInfo
denseCoderFields []*coderFieldInfo
coderFields map [protowire .Number ]*coderFieldInfo
sizecacheOffset offset
unknownOffset offset
extensionOffset offset
needsInitCheck bool
isMessageSet bool
numRequiredFields uint8
}
type coderFieldInfo struct {
funcs pointerCoderFuncs
mi *MessageInfo
ft reflect .Type
validation validationInfo
num pref .FieldNumber
offset offset
wiretag uint64
tagsize int
isPointer bool
isRequired bool
}
func (mi *MessageInfo ) makeCoderMethods (t reflect .Type , si structInfo ) {
mi .sizecacheOffset = si .sizecacheOffset
mi .unknownOffset = si .unknownOffset
mi .extensionOffset = si .extensionOffset
mi .coderFields = make (map [protowire .Number ]*coderFieldInfo )
fields := mi .Desc .Fields ()
preallocFields := make ([]coderFieldInfo , fields .Len ())
for i := 0 ; i < fields .Len (); i ++ {
fd := fields .Get (i )
fs := si .fieldsByNumber [fd .Number ()]
isOneof := fd .ContainingOneof () != nil && !fd .ContainingOneof ().IsSynthetic ()
if isOneof {
fs = si .oneofsByName [fd .ContainingOneof ().Name ()]
}
ft := fs .Type
var wiretag uint64
if !fd .IsPacked () {
wiretag = protowire .EncodeTag (fd .Number (), wireTypes [fd .Kind ()])
} else {
wiretag = protowire .EncodeTag (fd .Number (), protowire .BytesType )
}
var fieldOffset offset
var funcs pointerCoderFuncs
var childMessage *MessageInfo
switch {
case isOneof :
fieldOffset = offsetOf (fs , mi .Exporter )
case fd .IsWeak ():
fieldOffset = si .weakOffset
funcs = makeWeakMessageFieldCoder (fd )
default :
fieldOffset = offsetOf (fs , mi .Exporter )
childMessage , funcs = fieldCoder (fd , ft )
}
cf := &preallocFields [i ]
*cf = coderFieldInfo {
num : fd .Number (),
offset : fieldOffset ,
wiretag : wiretag ,
ft : ft ,
tagsize : protowire .SizeVarint (wiretag ),
funcs : funcs ,
mi : childMessage ,
validation : newFieldValidationInfo (mi , si , fd , ft ),
isPointer : fd .Cardinality () == pref .Repeated || fd .HasPresence (),
isRequired : fd .Cardinality () == pref .Required ,
}
mi .orderedCoderFields = append (mi .orderedCoderFields , cf )
mi .coderFields [cf .num ] = cf
}
for i , oneofs := 0 , mi .Desc .Oneofs (); i < oneofs .Len (); i ++ {
if od := oneofs .Get (i ); !od .IsSynthetic () {
mi .initOneofFieldCoders (od , si )
}
}
if messageset .IsMessageSet (mi .Desc ) {
if !mi .extensionOffset .IsValid () {
panic (fmt .Sprintf ("%v: MessageSet with no extensions field" , mi .Desc .FullName ()))
}
if !mi .unknownOffset .IsValid () {
panic (fmt .Sprintf ("%v: MessageSet with no unknown field" , mi .Desc .FullName ()))
}
mi .isMessageSet = true
}
sort .Slice (mi .orderedCoderFields , func (i , j int ) bool {
return mi .orderedCoderFields [i ].num < mi .orderedCoderFields [j ].num
})
var maxDense pref .FieldNumber
for _ , cf := range mi .orderedCoderFields {
if cf .num >= 16 && cf .num >= 2 *maxDense {
break
}
maxDense = cf .num
}
mi .denseCoderFields = make ([]*coderFieldInfo , maxDense +1 )
for _ , cf := range mi .orderedCoderFields {
if int (cf .num ) >= len (mi .denseCoderFields ) {
break
}
mi .denseCoderFields [cf .num ] = cf
}