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 func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { |
14 func newListConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter { |
15 switch { |
15 switch { |
16 case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice: |
16 case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice: |
17 return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)} |
17 return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)} |
18 case t.Kind() == reflect.Slice: |
18 case t.Kind() == reflect.Slice: |
19 return &listConverter{t, newSingularConverter(t.Elem(), fd)} |
19 return &listConverter{t, newSingularConverter(t.Elem(), fd)} |
24 type listConverter struct { |
24 type listConverter struct { |
25 goType reflect.Type // []T |
25 goType reflect.Type // []T |
26 c Converter |
26 c Converter |
27 } |
27 } |
28 |
28 |
29 func (c *listConverter) PBValueOf(v reflect.Value) pref.Value { |
29 func (c *listConverter) PBValueOf(v reflect.Value) protoreflect.Value { |
30 if v.Type() != c.goType { |
30 if v.Type() != c.goType { |
31 panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
31 panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
32 } |
32 } |
33 pv := reflect.New(c.goType) |
33 pv := reflect.New(c.goType) |
34 pv.Elem().Set(v) |
34 pv.Elem().Set(v) |
35 return pref.ValueOfList(&listReflect{pv, c.c}) |
35 return protoreflect.ValueOfList(&listReflect{pv, c.c}) |
36 } |
36 } |
37 |
37 |
38 func (c *listConverter) GoValueOf(v pref.Value) reflect.Value { |
38 func (c *listConverter) GoValueOf(v protoreflect.Value) reflect.Value { |
39 rv := v.List().(*listReflect).v |
39 rv := v.List().(*listReflect).v |
40 if rv.IsNil() { |
40 if rv.IsNil() { |
41 return reflect.Zero(c.goType) |
41 return reflect.Zero(c.goType) |
42 } |
42 } |
43 return rv.Elem() |
43 return rv.Elem() |
44 } |
44 } |
45 |
45 |
46 func (c *listConverter) IsValidPB(v pref.Value) bool { |
46 func (c *listConverter) IsValidPB(v protoreflect.Value) bool { |
47 list, ok := v.Interface().(*listReflect) |
47 list, ok := v.Interface().(*listReflect) |
48 if !ok { |
48 if !ok { |
49 return false |
49 return false |
50 } |
50 } |
51 return list.v.Type().Elem() == c.goType |
51 return list.v.Type().Elem() == c.goType |
53 |
53 |
54 func (c *listConverter) IsValidGo(v reflect.Value) bool { |
54 func (c *listConverter) IsValidGo(v reflect.Value) bool { |
55 return v.IsValid() && v.Type() == c.goType |
55 return v.IsValid() && v.Type() == c.goType |
56 } |
56 } |
57 |
57 |
58 func (c *listConverter) New() pref.Value { |
58 func (c *listConverter) New() protoreflect.Value { |
59 return pref.ValueOfList(&listReflect{reflect.New(c.goType), c.c}) |
59 return protoreflect.ValueOfList(&listReflect{reflect.New(c.goType), c.c}) |
60 } |
60 } |
61 |
61 |
62 func (c *listConverter) Zero() pref.Value { |
62 func (c *listConverter) Zero() protoreflect.Value { |
63 return pref.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c}) |
63 return protoreflect.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c}) |
64 } |
64 } |
65 |
65 |
66 type listPtrConverter struct { |
66 type listPtrConverter struct { |
67 goType reflect.Type // *[]T |
67 goType reflect.Type // *[]T |
68 c Converter |
68 c Converter |
69 } |
69 } |
70 |
70 |
71 func (c *listPtrConverter) PBValueOf(v reflect.Value) pref.Value { |
71 func (c *listPtrConverter) PBValueOf(v reflect.Value) protoreflect.Value { |
72 if v.Type() != c.goType { |
72 if v.Type() != c.goType { |
73 panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
73 panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) |
74 } |
74 } |
75 return pref.ValueOfList(&listReflect{v, c.c}) |
75 return protoreflect.ValueOfList(&listReflect{v, c.c}) |
76 } |
76 } |
77 |
77 |
78 func (c *listPtrConverter) GoValueOf(v pref.Value) reflect.Value { |
78 func (c *listPtrConverter) GoValueOf(v protoreflect.Value) reflect.Value { |
79 return v.List().(*listReflect).v |
79 return v.List().(*listReflect).v |
80 } |
80 } |
81 |
81 |
82 func (c *listPtrConverter) IsValidPB(v pref.Value) bool { |
82 func (c *listPtrConverter) IsValidPB(v protoreflect.Value) bool { |
83 list, ok := v.Interface().(*listReflect) |
83 list, ok := v.Interface().(*listReflect) |
84 if !ok { |
84 if !ok { |
85 return false |
85 return false |
86 } |
86 } |
87 return list.v.Type() == c.goType |
87 return list.v.Type() == c.goType |
89 |
89 |
90 func (c *listPtrConverter) IsValidGo(v reflect.Value) bool { |
90 func (c *listPtrConverter) IsValidGo(v reflect.Value) bool { |
91 return v.IsValid() && v.Type() == c.goType |
91 return v.IsValid() && v.Type() == c.goType |
92 } |
92 } |
93 |
93 |
94 func (c *listPtrConverter) New() pref.Value { |
94 func (c *listPtrConverter) New() protoreflect.Value { |
95 return c.PBValueOf(reflect.New(c.goType.Elem())) |
95 return c.PBValueOf(reflect.New(c.goType.Elem())) |
96 } |
96 } |
97 |
97 |
98 func (c *listPtrConverter) Zero() pref.Value { |
98 func (c *listPtrConverter) Zero() protoreflect.Value { |
99 return c.PBValueOf(reflect.Zero(c.goType)) |
99 return c.PBValueOf(reflect.Zero(c.goType)) |
100 } |
100 } |
101 |
101 |
102 type listReflect struct { |
102 type listReflect struct { |
103 v reflect.Value // *[]T |
103 v reflect.Value // *[]T |
108 if ls.v.IsNil() { |
108 if ls.v.IsNil() { |
109 return 0 |
109 return 0 |
110 } |
110 } |
111 return ls.v.Elem().Len() |
111 return ls.v.Elem().Len() |
112 } |
112 } |
113 func (ls *listReflect) Get(i int) pref.Value { |
113 func (ls *listReflect) Get(i int) protoreflect.Value { |
114 return ls.conv.PBValueOf(ls.v.Elem().Index(i)) |
114 return ls.conv.PBValueOf(ls.v.Elem().Index(i)) |
115 } |
115 } |
116 func (ls *listReflect) Set(i int, v pref.Value) { |
116 func (ls *listReflect) Set(i int, v protoreflect.Value) { |
117 ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v)) |
117 ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v)) |
118 } |
118 } |
119 func (ls *listReflect) Append(v pref.Value) { |
119 func (ls *listReflect) Append(v protoreflect.Value) { |
120 ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v))) |
120 ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v))) |
121 } |
121 } |
122 func (ls *listReflect) AppendMutable() pref.Value { |
122 func (ls *listReflect) AppendMutable() protoreflect.Value { |
123 if _, ok := ls.conv.(*messageConverter); !ok { |
123 if _, ok := ls.conv.(*messageConverter); !ok { |
124 panic("invalid AppendMutable on list with non-message type") |
124 panic("invalid AppendMutable on list with non-message type") |
125 } |
125 } |
126 v := ls.NewElement() |
126 v := ls.NewElement() |
127 ls.Append(v) |
127 ls.Append(v) |
128 return v |
128 return v |
129 } |
129 } |
130 func (ls *listReflect) Truncate(i int) { |
130 func (ls *listReflect) Truncate(i int) { |
131 ls.v.Elem().Set(ls.v.Elem().Slice(0, i)) |
131 ls.v.Elem().Set(ls.v.Elem().Slice(0, i)) |
132 } |
132 } |
133 func (ls *listReflect) NewElement() pref.Value { |
133 func (ls *listReflect) NewElement() protoreflect.Value { |
134 return ls.conv.New() |
134 return ls.conv.New() |
135 } |
135 } |
136 func (ls *listReflect) IsValid() bool { |
136 func (ls *listReflect) IsValid() bool { |
137 return !ls.v.IsNil() |
137 return !ls.v.IsNil() |
138 } |
138 } |