github.com/phpstudyer/protoreflect@v1.7.2/dynamic/maps_1.11.go (about) 1 //+build !go1.12 2 3 package dynamic 4 5 import ( 6 "github.com/phpstudyer/protoreflect/desc" 7 "reflect" 8 ) 9 10 // Pre-Go-1.12, we must use reflect.Value.MapKeys to reflectively 11 // iterate a map. (We can be more efficient in Go 1.12 and up...) 12 13 func mapsEqual(a, b reflect.Value) bool { 14 if a.Len() != b.Len() { 15 return false 16 } 17 if a.Len() == 0 && b.Len() == 0 { 18 // Optimize the case where maps are frequently empty because MapKeys() 19 // function allocates heavily. 20 return true 21 } 22 23 for _, k := range a.MapKeys() { 24 av := a.MapIndex(k) 25 bv := b.MapIndex(k) 26 if !bv.IsValid() { 27 return false 28 } 29 if !fieldsEqual(av.Interface(), bv.Interface()) { 30 return false 31 } 32 } 33 return true 34 } 35 36 func validFieldValueForMapField(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) { 37 // make a defensive copy while we check the contents 38 // (also converts to map[interface{}]interface{} if it's some other type) 39 keyField := fd.GetMessageType().GetFields()[0] 40 valField := fd.GetMessageType().GetFields()[1] 41 m := map[interface{}]interface{}{} 42 for _, k := range val.MapKeys() { 43 if k.Kind() == reflect.Interface { 44 // unwrap it 45 k = reflect.ValueOf(k.Interface()) 46 } 47 kk, err := validElementFieldValueForRv(keyField, k, false) 48 if err != nil { 49 return nil, err 50 } 51 v := val.MapIndex(k) 52 if v.Kind() == reflect.Interface { 53 // unwrap it 54 v = reflect.ValueOf(v.Interface()) 55 } 56 vv, err := validElementFieldValueForRv(valField, v, true) 57 if err != nil { 58 return nil, err 59 } 60 m[kk] = vv 61 } 62 return m, nil 63 } 64 65 func canConvertMap(src reflect.Value, target reflect.Type) bool { 66 kt := target.Key() 67 vt := target.Elem() 68 for _, k := range src.MapKeys() { 69 if !canConvert(k, kt) { 70 return false 71 } 72 if !canConvert(src.MapIndex(k), vt) { 73 return false 74 } 75 } 76 return true 77 } 78 79 func mergeMapVal(src, target reflect.Value, targetType reflect.Type, deterministic bool) error { 80 tkt := targetType.Key() 81 tvt := targetType.Elem() 82 for _, k := range src.MapKeys() { 83 v := src.MapIndex(k) 84 skt := k.Type() 85 svt := v.Type() 86 var nk, nv reflect.Value 87 if tkt == skt { 88 nk = k 89 } else if tkt.Kind() == reflect.Ptr && tkt.Elem() == skt { 90 nk = k.Addr() 91 } else { 92 nk = reflect.New(tkt).Elem() 93 if err := mergeVal(k, nk, deterministic); err != nil { 94 return err 95 } 96 } 97 if tvt == svt { 98 nv = v 99 } else if tvt.Kind() == reflect.Ptr && tvt.Elem() == svt { 100 nv = v.Addr() 101 } else { 102 nv = reflect.New(tvt).Elem() 103 if err := mergeVal(v, nv, deterministic); err != nil { 104 return err 105 } 106 } 107 if target.IsNil() { 108 target.Set(reflect.MakeMap(targetType)) 109 } 110 target.SetMapIndex(nk, nv) 111 } 112 return nil 113 } 114 115 func mergeMapField(m *Message, fd *desc.FieldDescriptor, rv reflect.Value) error { 116 for _, k := range rv.MapKeys() { 117 if k.Kind() == reflect.Interface && !k.IsNil() { 118 k = k.Elem() 119 } 120 v := rv.MapIndex(k) 121 if v.Kind() == reflect.Interface && !v.IsNil() { 122 v = v.Elem() 123 } 124 if err := m.putMapField(fd, k.Interface(), v.Interface()); err != nil { 125 return err 126 } 127 } 128 return nil 129 }