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