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