blob: df92f02742b8fb37a95fa66c45f12aba531c0b3b [file] [log] [blame]
Joe Tsaif0c01e42018-11-06 13:05:20 -08001// 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
5package impl
6
7import (
Joe Tsaif0c01e42018-11-06 13:05:20 -08008 "reflect"
9
Joe Tsaif18ab532018-11-27 17:25:04 -080010 papi "github.com/golang/protobuf/protoapi"
Joe Tsaif0c01e42018-11-06 13:05:20 -080011 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
Joe Tsaif0c01e42018-11-06 13:05:20 -080012)
13
14func makeLegacyExtensionFieldsFunc(t reflect.Type) func(p *messageDataType) pref.KnownFields {
15 f := makeLegacyExtensionMapFunc(t)
16 if f == nil {
17 return nil
18 }
19 return func(p *messageDataType) pref.KnownFields {
20 return legacyExtensionFields{p.mi, f(p)}
21 }
22}
23
Joe Tsaif18ab532018-11-27 17:25:04 -080024var (
25 extTypeA = reflect.TypeOf(map[int32]papi.ExtensionField(nil))
26 extTypeB = reflect.TypeOf(papi.XXX_InternalExtensions{})
27)
28
29func makeLegacyExtensionMapFunc(t reflect.Type) func(*messageDataType) papi.ExtensionFields {
30 fx1, _ := t.FieldByName("XXX_extensions")
31 fx2, _ := t.FieldByName("XXX_InternalExtensions")
32 switch {
33 case fx1.Type == extTypeA:
34 fieldOffset := offsetOf(fx1)
35 return func(p *messageDataType) papi.ExtensionFields {
36 v := p.p.apply(fieldOffset).asType(fx1.Type).Interface()
37 return papi.ExtensionFieldsOf(v)
38 }
39 case fx2.Type == extTypeB:
40 fieldOffset := offsetOf(fx2)
41 return func(p *messageDataType) papi.ExtensionFields {
42 v := p.p.apply(fieldOffset).asType(fx2.Type).Interface()
43 return papi.ExtensionFieldsOf(v)
44 }
45 default:
46 return nil
47 }
48}
49
Joe Tsaif0c01e42018-11-06 13:05:20 -080050type legacyExtensionFields struct {
51 mi *MessageType
Joe Tsaif18ab532018-11-27 17:25:04 -080052 x papi.ExtensionFields
Joe Tsaif0c01e42018-11-06 13:05:20 -080053}
54
55func (p legacyExtensionFields) Len() (n int) {
Joe Tsaif18ab532018-11-27 17:25:04 -080056 p.x.Range(func(num pref.FieldNumber, _ papi.ExtensionField) bool {
57 if p.Has(pref.FieldNumber(num)) {
Joe Tsaif0c01e42018-11-06 13:05:20 -080058 n++
59 }
60 return true
61 })
62 return n
63}
64
65func (p legacyExtensionFields) Has(n pref.FieldNumber) bool {
66 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -080067 if x.Value == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -080068 return false
69 }
Joe Tsai08e00302018-11-26 22:32:06 -080070 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif0c01e42018-11-06 13:05:20 -080071 if t.Cardinality() == pref.Repeated {
Joe Tsaif18ab532018-11-27 17:25:04 -080072 return t.ValueOf(x.Value).List().Len() > 0
Joe Tsaif0c01e42018-11-06 13:05:20 -080073 }
74 return true
75}
76
77func (p legacyExtensionFields) Get(n pref.FieldNumber) pref.Value {
78 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -080079 if x.Desc == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -080080 return pref.Value{}
81 }
Joe Tsai08e00302018-11-26 22:32:06 -080082 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif18ab532018-11-27 17:25:04 -080083 if x.Value == nil {
84 // NOTE: x.Value is never nil for Lists since they are always populated
Joe Tsaif6d4a422018-11-19 14:26:06 -080085 // during ExtensionFieldTypes.Register.
Joe Tsaif0c01e42018-11-06 13:05:20 -080086 if t.Kind() == pref.MessageKind || t.Kind() == pref.GroupKind {
Joe Tsaif0c01e42018-11-06 13:05:20 -080087 return pref.Value{}
88 }
89 return t.Default()
90 }
Joe Tsaif18ab532018-11-27 17:25:04 -080091 return t.ValueOf(x.Value)
Joe Tsaif0c01e42018-11-06 13:05:20 -080092}
93
94func (p legacyExtensionFields) Set(n pref.FieldNumber, v pref.Value) {
95 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -080096 if x.Desc == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -080097 panic("no extension descriptor registered")
98 }
Joe Tsai08e00302018-11-26 22:32:06 -080099 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif18ab532018-11-27 17:25:04 -0800100 x.Value = t.InterfaceOf(v)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800101 p.x.Set(n, x)
102}
103
104func (p legacyExtensionFields) Clear(n pref.FieldNumber) {
105 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -0800106 if x.Desc == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800107 return
108 }
Joe Tsai08e00302018-11-26 22:32:06 -0800109 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800110 if t.Cardinality() == pref.Repeated {
Joe Tsaif18ab532018-11-27 17:25:04 -0800111 t.ValueOf(x.Value).List().Truncate(0)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800112 return
113 }
Joe Tsaif18ab532018-11-27 17:25:04 -0800114 x.Value = nil
Joe Tsaif0c01e42018-11-06 13:05:20 -0800115 p.x.Set(n, x)
116}
117
118func (p legacyExtensionFields) Mutable(n pref.FieldNumber) pref.Mutable {
119 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -0800120 if x.Desc == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800121 panic("no extension descriptor registered")
122 }
Joe Tsai08e00302018-11-26 22:32:06 -0800123 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif18ab532018-11-27 17:25:04 -0800124 if x.Value == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800125 v := t.ValueOf(t.New())
Joe Tsaif18ab532018-11-27 17:25:04 -0800126 x.Value = t.InterfaceOf(v)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800127 p.x.Set(n, x)
128 }
Joe Tsaif18ab532018-11-27 17:25:04 -0800129 return t.ValueOf(x.Value).Interface().(pref.Mutable)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800130}
131
132func (p legacyExtensionFields) Range(f func(pref.FieldNumber, pref.Value) bool) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800133 p.x.Range(func(n pref.FieldNumber, x papi.ExtensionField) bool {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800134 if p.Has(n) {
135 return f(n, p.Get(n))
136 }
137 return true
138 })
139}
140
141func (p legacyExtensionFields) ExtensionTypes() pref.ExtensionFieldTypes {
142 return legacyExtensionTypes(p)
143}
144
145type legacyExtensionTypes legacyExtensionFields
146
147func (p legacyExtensionTypes) Len() (n int) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800148 p.x.Range(func(_ pref.FieldNumber, x papi.ExtensionField) bool {
149 if x.Desc != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800150 n++
151 }
152 return true
153 })
154 return n
155}
156
157func (p legacyExtensionTypes) Register(t pref.ExtensionType) {
158 if p.mi.Type.FullName() != t.ExtendedType().FullName() {
159 panic("extended type mismatch")
160 }
161 if !p.mi.Type.ExtensionRanges().Has(t.Number()) {
162 panic("invalid extension field number")
163 }
164 x := p.x.Get(t.Number())
Joe Tsaif18ab532018-11-27 17:25:04 -0800165 if x.Desc != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800166 panic("extension descriptor already registered")
167 }
Joe Tsai08e00302018-11-26 22:32:06 -0800168 x.Desc = legacyWrapper.ExtensionDescFromType(t)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800169 if t.Cardinality() == pref.Repeated {
170 // If the field is repeated, initialize the entry with an empty list
171 // so that future Get operations can return a mutable and concrete list.
Joe Tsaif18ab532018-11-27 17:25:04 -0800172 x.Value = t.InterfaceOf(t.ValueOf(t.New()))
Joe Tsaif6d4a422018-11-19 14:26:06 -0800173 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800174 p.x.Set(t.Number(), x)
175}
176
177func (p legacyExtensionTypes) Remove(t pref.ExtensionType) {
178 if !p.mi.Type.ExtensionRanges().Has(t.Number()) {
179 return
180 }
181 x := p.x.Get(t.Number())
Joe Tsaif6d4a422018-11-19 14:26:06 -0800182 if t.Cardinality() == pref.Repeated {
183 // Treat an empty repeated field as unpopulated.
Joe Tsaif18ab532018-11-27 17:25:04 -0800184 v := reflect.ValueOf(x.Value)
185 if x.Value == nil || v.IsNil() || v.Elem().Len() == 0 {
186 x.Value = nil
Joe Tsaif6d4a422018-11-19 14:26:06 -0800187 }
188 }
Joe Tsaif18ab532018-11-27 17:25:04 -0800189 if x.Value != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800190 panic("value for extension descriptor still populated")
191 }
Joe Tsaif18ab532018-11-27 17:25:04 -0800192 x.Desc = nil
193 if len(x.Raw) == 0 {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800194 p.x.Clear(t.Number())
195 } else {
196 p.x.Set(t.Number(), x)
197 }
198}
199
200func (p legacyExtensionTypes) ByNumber(n pref.FieldNumber) pref.ExtensionType {
201 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -0800202 if x.Desc != nil {
Joe Tsai08e00302018-11-26 22:32:06 -0800203 return legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800204 }
205 return nil
206}
207
208func (p legacyExtensionTypes) ByName(s pref.FullName) (t pref.ExtensionType) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800209 p.x.Range(func(_ pref.FieldNumber, x papi.ExtensionField) bool {
210 if x.Desc != nil && x.Desc.Name == string(s) {
Joe Tsai08e00302018-11-26 22:32:06 -0800211 t = legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800212 return false
213 }
214 return true
215 })
216 return t
217}
218
219func (p legacyExtensionTypes) Range(f func(pref.ExtensionType) bool) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800220 p.x.Range(func(_ pref.FieldNumber, x papi.ExtensionField) bool {
221 if x.Desc != nil {
Joe Tsai08e00302018-11-26 22:32:06 -0800222 if !f(legacyWrapper.ExtensionTypeFromDesc(x.Desc)) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800223 return false
224 }
225 }
226 return true
227 })
228}