blob: 932dbf1144eaedbd4b83bbbe36e8fa8f37eadf99 [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 {
Joe Tsai6cf80c42018-12-01 04:57:09 -080020 if p.p.IsNil() {
21 return emptyExtensionFields{}
22 }
Joe Tsaif0c01e42018-11-06 13:05:20 -080023 return legacyExtensionFields{p.mi, f(p)}
24 }
25}
26
Joe Tsaif18ab532018-11-27 17:25:04 -080027var (
28 extTypeA = reflect.TypeOf(map[int32]papi.ExtensionField(nil))
29 extTypeB = reflect.TypeOf(papi.XXX_InternalExtensions{})
30)
31
32func makeLegacyExtensionMapFunc(t reflect.Type) func(*messageDataType) papi.ExtensionFields {
33 fx1, _ := t.FieldByName("XXX_extensions")
34 fx2, _ := t.FieldByName("XXX_InternalExtensions")
35 switch {
36 case fx1.Type == extTypeA:
37 fieldOffset := offsetOf(fx1)
38 return func(p *messageDataType) papi.ExtensionFields {
Joe Tsai6cf80c42018-12-01 04:57:09 -080039 v := p.p.Apply(fieldOffset).AsValueOf(fx1.Type).Interface()
Joe Tsaif18ab532018-11-27 17:25:04 -080040 return papi.ExtensionFieldsOf(v)
41 }
42 case fx2.Type == extTypeB:
43 fieldOffset := offsetOf(fx2)
44 return func(p *messageDataType) papi.ExtensionFields {
Joe Tsai6cf80c42018-12-01 04:57:09 -080045 v := p.p.Apply(fieldOffset).AsValueOf(fx2.Type).Interface()
Joe Tsaif18ab532018-11-27 17:25:04 -080046 return papi.ExtensionFieldsOf(v)
47 }
48 default:
49 return nil
50 }
51}
52
Joe Tsaif0c01e42018-11-06 13:05:20 -080053type legacyExtensionFields struct {
54 mi *MessageType
Joe Tsaif18ab532018-11-27 17:25:04 -080055 x papi.ExtensionFields
Joe Tsaif0c01e42018-11-06 13:05:20 -080056}
57
58func (p legacyExtensionFields) Len() (n int) {
Joe Tsaif18ab532018-11-27 17:25:04 -080059 p.x.Range(func(num pref.FieldNumber, _ papi.ExtensionField) bool {
60 if p.Has(pref.FieldNumber(num)) {
Joe Tsaif0c01e42018-11-06 13:05:20 -080061 n++
62 }
63 return true
64 })
65 return n
66}
67
68func (p legacyExtensionFields) Has(n pref.FieldNumber) bool {
69 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -080070 if x.Value == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -080071 return false
72 }
Joe Tsai08e00302018-11-26 22:32:06 -080073 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif0c01e42018-11-06 13:05:20 -080074 if t.Cardinality() == pref.Repeated {
Joe Tsaif18ab532018-11-27 17:25:04 -080075 return t.ValueOf(x.Value).List().Len() > 0
Joe Tsaif0c01e42018-11-06 13:05:20 -080076 }
77 return true
78}
79
80func (p legacyExtensionFields) Get(n pref.FieldNumber) pref.Value {
81 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -080082 if x.Desc == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -080083 return pref.Value{}
84 }
Joe Tsai08e00302018-11-26 22:32:06 -080085 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif18ab532018-11-27 17:25:04 -080086 if x.Value == nil {
87 // NOTE: x.Value is never nil for Lists since they are always populated
Joe Tsaif6d4a422018-11-19 14:26:06 -080088 // during ExtensionFieldTypes.Register.
Joe Tsaif0c01e42018-11-06 13:05:20 -080089 if t.Kind() == pref.MessageKind || t.Kind() == pref.GroupKind {
Joe Tsaif0c01e42018-11-06 13:05:20 -080090 return pref.Value{}
91 }
92 return t.Default()
93 }
Joe Tsaif18ab532018-11-27 17:25:04 -080094 return t.ValueOf(x.Value)
Joe Tsaif0c01e42018-11-06 13:05:20 -080095}
96
97func (p legacyExtensionFields) Set(n pref.FieldNumber, v pref.Value) {
98 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -080099 if x.Desc == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800100 panic("no extension descriptor registered")
101 }
Joe Tsai08e00302018-11-26 22:32:06 -0800102 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif18ab532018-11-27 17:25:04 -0800103 x.Value = t.InterfaceOf(v)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800104 p.x.Set(n, x)
105}
106
107func (p legacyExtensionFields) Clear(n pref.FieldNumber) {
108 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -0800109 if x.Desc == nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800110 return
111 }
Joe Tsai08e00302018-11-26 22:32:06 -0800112 t := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800113 if t.Cardinality() == pref.Repeated {
Joe Tsaif18ab532018-11-27 17:25:04 -0800114 t.ValueOf(x.Value).List().Truncate(0)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800115 return
116 }
Joe Tsaif18ab532018-11-27 17:25:04 -0800117 x.Value = nil
Joe Tsaif0c01e42018-11-06 13:05:20 -0800118 p.x.Set(n, x)
119}
120
Joe Tsaif0c01e42018-11-06 13:05:20 -0800121func (p legacyExtensionFields) Range(f func(pref.FieldNumber, pref.Value) bool) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800122 p.x.Range(func(n pref.FieldNumber, x papi.ExtensionField) bool {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800123 if p.Has(n) {
124 return f(n, p.Get(n))
125 }
126 return true
127 })
128}
129
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800130func (p legacyExtensionFields) NewMessage(n pref.FieldNumber) pref.Message {
Damien Neil97e7f572018-12-07 14:28:33 -0800131 x := p.x.Get(n)
132 if x.Desc == nil {
133 panic("no extension descriptor registered")
134 }
135 xt := legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaid18bd312019-01-09 03:23:55 -0800136 return xt.New().Message()
Damien Neil97e7f572018-12-07 14:28:33 -0800137}
138
Joe Tsaif0c01e42018-11-06 13:05:20 -0800139func (p legacyExtensionFields) ExtensionTypes() pref.ExtensionFieldTypes {
140 return legacyExtensionTypes(p)
141}
142
143type legacyExtensionTypes legacyExtensionFields
144
145func (p legacyExtensionTypes) Len() (n int) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800146 p.x.Range(func(_ pref.FieldNumber, x papi.ExtensionField) bool {
147 if x.Desc != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800148 n++
149 }
150 return true
151 })
152 return n
153}
154
155func (p legacyExtensionTypes) Register(t pref.ExtensionType) {
Damien Neil8012b442019-01-18 09:32:24 -0800156 if p.mi.PBType.FullName() != t.ExtendedType().FullName() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800157 panic("extended type mismatch")
158 }
Damien Neil8012b442019-01-18 09:32:24 -0800159 if !p.mi.PBType.ExtensionRanges().Has(t.Number()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800160 panic("invalid extension field number")
161 }
162 x := p.x.Get(t.Number())
Joe Tsaif18ab532018-11-27 17:25:04 -0800163 if x.Desc != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800164 panic("extension descriptor already registered")
165 }
Joe Tsai08e00302018-11-26 22:32:06 -0800166 x.Desc = legacyWrapper.ExtensionDescFromType(t)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800167 if t.Cardinality() == pref.Repeated {
168 // If the field is repeated, initialize the entry with an empty list
169 // so that future Get operations can return a mutable and concrete list.
Joe Tsaid18bd312019-01-09 03:23:55 -0800170 x.Value = t.InterfaceOf(t.New())
Joe Tsaif6d4a422018-11-19 14:26:06 -0800171 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800172 p.x.Set(t.Number(), x)
173}
174
175func (p legacyExtensionTypes) Remove(t pref.ExtensionType) {
Damien Neil8012b442019-01-18 09:32:24 -0800176 if !p.mi.PBType.ExtensionRanges().Has(t.Number()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800177 return
178 }
179 x := p.x.Get(t.Number())
Joe Tsaif6d4a422018-11-19 14:26:06 -0800180 if t.Cardinality() == pref.Repeated {
181 // Treat an empty repeated field as unpopulated.
Joe Tsaif18ab532018-11-27 17:25:04 -0800182 v := reflect.ValueOf(x.Value)
183 if x.Value == nil || v.IsNil() || v.Elem().Len() == 0 {
184 x.Value = nil
Joe Tsaif6d4a422018-11-19 14:26:06 -0800185 }
186 }
Joe Tsaif18ab532018-11-27 17:25:04 -0800187 if x.Value != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800188 panic("value for extension descriptor still populated")
189 }
Joe Tsaif18ab532018-11-27 17:25:04 -0800190 x.Desc = nil
191 if len(x.Raw) == 0 {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800192 p.x.Clear(t.Number())
193 } else {
194 p.x.Set(t.Number(), x)
195 }
196}
197
198func (p legacyExtensionTypes) ByNumber(n pref.FieldNumber) pref.ExtensionType {
199 x := p.x.Get(n)
Joe Tsaif18ab532018-11-27 17:25:04 -0800200 if x.Desc != nil {
Joe Tsai08e00302018-11-26 22:32:06 -0800201 return legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800202 }
203 return nil
204}
205
206func (p legacyExtensionTypes) ByName(s pref.FullName) (t pref.ExtensionType) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800207 p.x.Range(func(_ pref.FieldNumber, x papi.ExtensionField) bool {
208 if x.Desc != nil && x.Desc.Name == string(s) {
Joe Tsai08e00302018-11-26 22:32:06 -0800209 t = legacyWrapper.ExtensionTypeFromDesc(x.Desc)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800210 return false
211 }
212 return true
213 })
214 return t
215}
216
217func (p legacyExtensionTypes) Range(f func(pref.ExtensionType) bool) {
Joe Tsaif18ab532018-11-27 17:25:04 -0800218 p.x.Range(func(_ pref.FieldNumber, x papi.ExtensionField) bool {
219 if x.Desc != nil {
Joe Tsai08e00302018-11-26 22:32:06 -0800220 if !f(legacyWrapper.ExtensionTypeFromDesc(x.Desc)) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800221 return false
222 }
223 }
224 return true
225 })
226}