convert_map.go (3102B)
1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package impl 6 7 import ( 8 "fmt" 9 "reflect" 10 11 "google.golang.org/protobuf/reflect/protoreflect" 12 ) 13 14 type mapConverter struct { 15 goType reflect.Type // map[K]V 16 keyConv, valConv Converter 17 } 18 19 func newMapConverter(t reflect.Type, fd protoreflect.FieldDescriptor) *mapConverter { 20 if t.Kind() != reflect.Map { 21 panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) 22 } 23 return &mapConverter{ 24 goType: t, 25 keyConv: newSingularConverter(t.Key(), fd.MapKey()), 26 valConv: newSingularConverter(t.Elem(), fd.MapValue()), 27 } 28 } 29 30 func (c *mapConverter) PBValueOf(v reflect.Value) protoreflect.Value { 31 if v.Type() != c.goType { 32 panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 33 } 34 return protoreflect.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv}) 35 } 36 37 func (c *mapConverter) GoValueOf(v protoreflect.Value) reflect.Value { 38 return v.Map().(*mapReflect).v 39 } 40 41 func (c *mapConverter) IsValidPB(v protoreflect.Value) bool { 42 mapv, ok := v.Interface().(*mapReflect) 43 if !ok { 44 return false 45 } 46 return mapv.v.Type() == c.goType 47 } 48 49 func (c *mapConverter) IsValidGo(v reflect.Value) bool { 50 return v.IsValid() && v.Type() == c.goType 51 } 52 53 func (c *mapConverter) New() protoreflect.Value { 54 return c.PBValueOf(reflect.MakeMap(c.goType)) 55 } 56 57 func (c *mapConverter) Zero() protoreflect.Value { 58 return c.PBValueOf(reflect.Zero(c.goType)) 59 } 60 61 type mapReflect struct { 62 v reflect.Value // map[K]V 63 keyConv Converter 64 valConv Converter 65 } 66 67 func (ms *mapReflect) Len() int { 68 return ms.v.Len() 69 } 70 func (ms *mapReflect) Has(k protoreflect.MapKey) bool { 71 rk := ms.keyConv.GoValueOf(k.Value()) 72 rv := ms.v.MapIndex(rk) 73 return rv.IsValid() 74 } 75 func (ms *mapReflect) Get(k protoreflect.MapKey) protoreflect.Value { 76 rk := ms.keyConv.GoValueOf(k.Value()) 77 rv := ms.v.MapIndex(rk) 78 if !rv.IsValid() { 79 return protoreflect.Value{} 80 } 81 return ms.valConv.PBValueOf(rv) 82 } 83 func (ms *mapReflect) Set(k protoreflect.MapKey, v protoreflect.Value) { 84 rk := ms.keyConv.GoValueOf(k.Value()) 85 rv := ms.valConv.GoValueOf(v) 86 ms.v.SetMapIndex(rk, rv) 87 } 88 func (ms *mapReflect) Clear(k protoreflect.MapKey) { 89 rk := ms.keyConv.GoValueOf(k.Value()) 90 ms.v.SetMapIndex(rk, reflect.Value{}) 91 } 92 func (ms *mapReflect) Mutable(k protoreflect.MapKey) protoreflect.Value { 93 if _, ok := ms.valConv.(*messageConverter); !ok { 94 panic("invalid Mutable on map with non-message value type") 95 } 96 v := ms.Get(k) 97 if !v.IsValid() { 98 v = ms.NewValue() 99 ms.Set(k, v) 100 } 101 return v 102 } 103 func (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { 104 iter := mapRange(ms.v) 105 for iter.Next() { 106 k := ms.keyConv.PBValueOf(iter.Key()).MapKey() 107 v := ms.valConv.PBValueOf(iter.Value()) 108 if !f(k, v) { 109 return 110 } 111 } 112 } 113 func (ms *mapReflect) NewValue() protoreflect.Value { 114 return ms.valConv.New() 115 } 116 func (ms *mapReflect) IsValid() bool { 117 return !ms.v.IsNil() 118 } 119 func (ms *mapReflect) protoUnwrap() interface{} { 120 return ms.v.Interface() 121 }