package impl
import (
)
type mapInfo struct {
goType reflect.Type
keyWiretag uint64
valWiretag uint64
keyFuncs valueCoderFuncs
valFuncs valueCoderFuncs
keyZero protoreflect.Value
keyKind protoreflect.Kind
conv *mapConverter
}
func ( protoreflect.FieldDescriptor, reflect.Type) ( *MessageInfo, pointerCoderFuncs) {
:= .MapKey()
:= .MapValue()
:= protowire.EncodeTag(1, wireTypes[.Kind()])
:= protowire.EncodeTag(2, wireTypes[.Kind()])
:= encoderFuncsForValue()
:= encoderFuncsForValue()
:= newMapConverter(, )
:= &mapInfo{
goType: ,
keyWiretag: ,
valWiretag: ,
keyFuncs: ,
valFuncs: ,
keyZero: .Default(),
keyKind: .Kind(),
conv: ,
}
if .Kind() == protoreflect.MessageKind {
= getMessageInfo(.Elem())
}
= pointerCoderFuncs{
size: func( pointer, *coderFieldInfo, marshalOptions) int {
return sizeMap(.AsValueOf().Elem(), , , )
},
marshal: func( []byte, pointer, *coderFieldInfo, marshalOptions) ([]byte, error) {
return appendMap(, .AsValueOf().Elem(), , , )
},
unmarshal: func( []byte, pointer, protowire.Type, *coderFieldInfo, unmarshalOptions) (unmarshalOutput, error) {
:= .AsValueOf()
if .Elem().IsNil() {
.Elem().Set(reflect.MakeMap(.goType))
}
if .mi == nil {
return consumeMap(, .Elem(), , , , )
} else {
return consumeMapOfMessage(, .Elem(), , , , )
}
},
}
switch .Kind() {
case protoreflect.MessageKind:
.merge = mergeMapOfMessage
case protoreflect.BytesKind:
.merge = mergeMapOfBytes
default:
.merge = mergeMap
}
if .isInit != nil {
.isInit = func( pointer, *coderFieldInfo) error {
return isInitMap(.AsValueOf().Elem(), , )
}
}
return ,
}
const (
mapKeyTagSize = 1
mapValTagSize = 1
)
func ( reflect.Value, *mapInfo, *coderFieldInfo, marshalOptions) int {
if .Len() == 0 {
return 0
}
:= 0
:= mapRange()
for .Next() {
:= .conv.keyConv.PBValueOf(.Key()).MapKey()
:= .keyFuncs.size(.Value(), mapKeyTagSize, )
var int
:= .conv.valConv.PBValueOf(.Value())
if .mi == nil {
= .valFuncs.size(, mapValTagSize, )
} else {
:= pointerOfValue(.Value())
+= mapValTagSize
+= protowire.SizeBytes(.mi.sizePointer(, ))
}
+= .tagsize + protowire.SizeBytes(+)
}
return
}
func ( []byte, reflect.Value, protowire.Type, *mapInfo, *coderFieldInfo, unmarshalOptions) ( unmarshalOutput, error) {
if != protowire.BytesType {
return , errUnknown
}
, := protowire.ConsumeBytes()
if < 0 {
return , errDecode
}
var (
= .keyZero
= .conv.valConv.New()
)
for len() > 0 {
, , := protowire.ConsumeTag()
if < 0 {
return , errDecode
}
if > protowire.MaxValidNumber {
return , errDecode
}
= [:]
:= errUnknown
switch {
case genid.MapEntry_Key_field_number:
var protoreflect.Value
var unmarshalOutput
, , = .keyFuncs.unmarshal(, , , , )
if != nil {
break
}
=
= .n
case genid.MapEntry_Value_field_number:
var protoreflect.Value
var unmarshalOutput
, , = .valFuncs.unmarshal(, , , , )
if != nil {
break
}
=
= .n
}
if == errUnknown {
= protowire.ConsumeFieldValue(, , )
if < 0 {
return , errDecode
}
} else if != nil {
return ,
}
= [:]
}
.SetMapIndex(.conv.keyConv.GoValueOf(), .conv.valConv.GoValueOf())
.n =
return , nil
}
func ( []byte, reflect.Value, protowire.Type, *mapInfo, *coderFieldInfo, unmarshalOptions) ( unmarshalOutput, error) {
if != protowire.BytesType {
return , errUnknown
}
, := protowire.ConsumeBytes()
if < 0 {
return , errDecode
}
var (
= .keyZero
= reflect.New(.mi.GoReflectType.Elem())
)
for len() > 0 {
, , := protowire.ConsumeTag()
if < 0 {
return , errDecode
}
if > protowire.MaxValidNumber {
return , errDecode
}
= [:]
:= errUnknown
switch {
case 1:
var protoreflect.Value
var unmarshalOutput
, , = .keyFuncs.unmarshal(, , , , )
if != nil {
break
}
=
= .n
case 2:
if != protowire.BytesType {
break
}
var []byte
, = protowire.ConsumeBytes()
if < 0 {
return , errDecode
}
var unmarshalOutput
, = .mi.unmarshalPointer(, pointerOfValue(), 0, )
if .initialized {
.initialized = true
}
}
if == errUnknown {
= protowire.ConsumeFieldValue(, , )
if < 0 {
return , errDecode
}
} else if != nil {
return ,
}
= [:]
}
.SetMapIndex(.conv.keyConv.GoValueOf(), )
.n =
return , nil
}
func ( []byte, , reflect.Value, *mapInfo, *coderFieldInfo, marshalOptions) ([]byte, error) {
if .mi == nil {
:= .conv.keyConv.PBValueOf().MapKey()
:= .conv.valConv.PBValueOf()
:= 0
+= .keyFuncs.size(.Value(), mapKeyTagSize, )
+= .valFuncs.size(, mapValTagSize, )
= protowire.AppendVarint(, uint64())
, := .keyFuncs.marshal(, .Value(), .keyWiretag, )
if != nil {
return nil,
}
return .valFuncs.marshal(, , .valWiretag, )
} else {
:= .conv.keyConv.PBValueOf().MapKey()
:= pointerOfValue()
:= .mi.sizePointer(, )
:= 0
+= .keyFuncs.size(.Value(), mapKeyTagSize, )
+= mapValTagSize + protowire.SizeBytes()
= protowire.AppendVarint(, uint64())
, := .keyFuncs.marshal(, .Value(), .keyWiretag, )
if != nil {
return nil,
}
= protowire.AppendVarint(, .valWiretag)
= protowire.AppendVarint(, uint64())
return .mi.marshalAppendPointer(, , )
}
}
func ( []byte, reflect.Value, *mapInfo, *coderFieldInfo, marshalOptions) ([]byte, error) {
if .Len() == 0 {
return , nil
}
if .Deterministic() {
return appendMapDeterministic(, , , , )
}
:= mapRange()
for .Next() {
var error
= protowire.AppendVarint(, .wiretag)
, = appendMapItem(, .Key(), .Value(), , , )
if != nil {
return ,
}
}
return , nil
}
func ( []byte, reflect.Value, *mapInfo, *coderFieldInfo, marshalOptions) ([]byte, error) {
:= .MapKeys()
sort.Slice(, func(, int) bool {
switch [].Kind() {
case reflect.Bool:
return ![].Bool() && [].Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return [].Int() < [].Int()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return [].Uint() < [].Uint()
case reflect.Float32, reflect.Float64:
return [].Float() < [].Float()
case reflect.String:
return [].String() < [].String()
default:
panic("invalid kind: " + [].Kind().String())
}
})
for , := range {
var error
= protowire.AppendVarint(, .wiretag)
, = appendMapItem(, , .MapIndex(), , , )
if != nil {
return ,
}
}
return , nil
}
func ( reflect.Value, *mapInfo, *coderFieldInfo) error {
if := .mi; != nil {
.init()
if !.needsInitCheck {
return nil
}
:= mapRange()
for .Next() {
:= pointerOfValue(.Value())
if := .checkInitializedPointer(); != nil {
return
}
}
} else {
:= mapRange()
for .Next() {
:= .conv.valConv.PBValueOf(.Value())
if := .valFuncs.isInit(); != nil {
return
}
}
}
return nil
}
func (, pointer, *coderFieldInfo, mergeOptions) {
:= .AsValueOf(.ft).Elem()
:= .AsValueOf(.ft).Elem()
if .Len() == 0 {
return
}
if .IsNil() {
.Set(reflect.MakeMap(.ft))
}
:= mapRange()
for .Next() {
.SetMapIndex(.Key(), .Value())
}
}
func (, pointer, *coderFieldInfo, mergeOptions) {
:= .AsValueOf(.ft).Elem()
:= .AsValueOf(.ft).Elem()
if .Len() == 0 {
return
}
if .IsNil() {
.Set(reflect.MakeMap(.ft))
}
:= mapRange()
for .Next() {
.SetMapIndex(.Key(), reflect.ValueOf(append(emptyBuf[:], .Value().Bytes()...)))
}
}
func (, pointer, *coderFieldInfo, mergeOptions) {
:= .AsValueOf(.ft).Elem()
:= .AsValueOf(.ft).Elem()
if .Len() == 0 {
return
}
if .IsNil() {
.Set(reflect.MakeMap(.ft))
}
:= mapRange()
for .Next() {
:= reflect.New(.ft.Elem().Elem())
if .mi != nil {
.mi.mergePointer(pointerOfValue(), pointerOfValue(.Value()), )
} else {
.Merge(asMessage(), asMessage(.Value()))
}
.SetMapIndex(.Key(), )
}
}