blob: b53777578cd8eee4b795641c482481a8d9c0d962 [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
Damien Neile89e6242019-05-13 23:55:40 -070010 pref "google.golang.org/protobuf/reflect/protoreflect"
Joe Tsaif0c01e42018-11-06 13:05:20 -080011)
12
13func makeLegacyExtensionFieldsFunc(t reflect.Type) func(p *messageDataType) pref.KnownFields {
14 f := makeLegacyExtensionMapFunc(t)
15 if f == nil {
16 return nil
17 }
18 return func(p *messageDataType) pref.KnownFields {
Joe Tsai6cf80c42018-12-01 04:57:09 -080019 if p.p.IsNil() {
20 return emptyExtensionFields{}
21 }
Joe Tsaif0c01e42018-11-06 13:05:20 -080022 return legacyExtensionFields{p.mi, f(p)}
23 }
24}
25
Joe Tsai89d49632019-06-04 16:20:00 -070026var extType = reflect.TypeOf(map[int32]ExtensionField{})
Joe Tsaif18ab532018-11-27 17:25:04 -080027
Joe Tsai50c16712019-04-16 01:18:50 -070028func makeLegacyExtensionMapFunc(t reflect.Type) func(*messageDataType) *legacyExtensionMap {
29 fx, _ := t.FieldByName("XXX_extensions")
30 if fx.Type != extType {
31 fx, _ = t.FieldByName("XXX_InternalExtensions")
32 }
33 if fx.Type != extType {
Joe Tsaif18ab532018-11-27 17:25:04 -080034 return nil
35 }
Joe Tsai50c16712019-04-16 01:18:50 -070036
37 fieldOffset := offsetOf(fx)
38 return func(p *messageDataType) *legacyExtensionMap {
39 v := p.p.Apply(fieldOffset).AsValueOf(fx.Type).Interface()
Joe Tsai89d49632019-06-04 16:20:00 -070040 return (*legacyExtensionMap)(v.(*map[int32]ExtensionField))
Joe Tsai50c16712019-04-16 01:18:50 -070041 }
Joe Tsaif18ab532018-11-27 17:25:04 -080042}
43
Joe Tsaif0c01e42018-11-06 13:05:20 -080044type legacyExtensionFields struct {
Joe Tsai4fe96632019-05-22 05:12:36 -040045 mi *MessageInfo
Joe Tsai50c16712019-04-16 01:18:50 -070046 x *legacyExtensionMap
Joe Tsaif0c01e42018-11-06 13:05:20 -080047}
48
49func (p legacyExtensionFields) Len() (n int) {
Joe Tsai89d49632019-06-04 16:20:00 -070050 p.x.Range(func(num pref.FieldNumber, _ ExtensionField) bool {
Joe Tsaif18ab532018-11-27 17:25:04 -080051 if p.Has(pref.FieldNumber(num)) {
Joe Tsaif0c01e42018-11-06 13:05:20 -080052 n++
53 }
54 return true
55 })
56 return n
57}
58
59func (p legacyExtensionFields) Has(n pref.FieldNumber) bool {
60 x := p.x.Get(n)
Joe Tsai40b83d62019-05-16 11:45:52 -070061 if !x.HasValue() {
Joe Tsaif0c01e42018-11-06 13:05:20 -080062 return false
63 }
Joe Tsai89d49632019-06-04 16:20:00 -070064 t := x.GetType()
Joe Tsai0fc49f82019-05-01 12:29:25 -070065 d := t.Descriptor()
Joe Tsaiac31a352019-05-13 14:32:56 -070066 if d.IsList() {
Joe Tsai40b83d62019-05-16 11:45:52 -070067 return t.ValueOf(x.GetValue()).List().Len() > 0
Joe Tsaif0c01e42018-11-06 13:05:20 -080068 }
69 return true
70}
71
72func (p legacyExtensionFields) Get(n pref.FieldNumber) pref.Value {
73 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -070074 if !x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -080075 return pref.Value{}
76 }
Joe Tsai89d49632019-06-04 16:20:00 -070077 t := x.GetType()
Joe Tsai0fc49f82019-05-01 12:29:25 -070078 d := t.Descriptor()
Joe Tsai40b83d62019-05-16 11:45:52 -070079 if !x.HasValue() {
Joe Tsaif18ab532018-11-27 17:25:04 -080080 // NOTE: x.Value is never nil for Lists since they are always populated
Joe Tsaif6d4a422018-11-19 14:26:06 -080081 // during ExtensionFieldTypes.Register.
Joe Tsai0fc49f82019-05-01 12:29:25 -070082 if d.Kind() == pref.MessageKind || d.Kind() == pref.GroupKind {
Joe Tsaif0c01e42018-11-06 13:05:20 -080083 return pref.Value{}
84 }
Joe Tsai0fc49f82019-05-01 12:29:25 -070085 return d.Default()
Joe Tsaif0c01e42018-11-06 13:05:20 -080086 }
Joe Tsai40b83d62019-05-16 11:45:52 -070087 return t.ValueOf(x.GetValue())
Joe Tsaif0c01e42018-11-06 13:05:20 -080088}
89
90func (p legacyExtensionFields) Set(n pref.FieldNumber, v pref.Value) {
91 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -070092 if !x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -080093 panic("no extension descriptor registered")
94 }
Joe Tsai89d49632019-06-04 16:20:00 -070095 t := x.GetType()
Joe Tsai40b83d62019-05-16 11:45:52 -070096 x.SetEagerValue(t.InterfaceOf(v))
Joe Tsaif0c01e42018-11-06 13:05:20 -080097 p.x.Set(n, x)
98}
99
100func (p legacyExtensionFields) Clear(n pref.FieldNumber) {
101 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -0700102 if !x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800103 return
104 }
Joe Tsai89d49632019-06-04 16:20:00 -0700105 t := x.GetType()
Joe Tsai0fc49f82019-05-01 12:29:25 -0700106 d := t.Descriptor()
Joe Tsaiac31a352019-05-13 14:32:56 -0700107 if d.IsList() {
Joe Tsai40b83d62019-05-16 11:45:52 -0700108 t.ValueOf(x.GetValue()).List().Truncate(0)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800109 return
110 }
Joe Tsai40b83d62019-05-16 11:45:52 -0700111 x.SetEagerValue(nil)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800112 p.x.Set(n, x)
113}
114
Joe Tsai4ec39c72019-04-03 13:40:53 -0700115func (p legacyExtensionFields) WhichOneof(pref.Name) pref.FieldNumber {
116 return 0
117}
118
Joe Tsaif0c01e42018-11-06 13:05:20 -0800119func (p legacyExtensionFields) Range(f func(pref.FieldNumber, pref.Value) bool) {
Joe Tsai89d49632019-06-04 16:20:00 -0700120 p.x.Range(func(n pref.FieldNumber, x ExtensionField) bool {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800121 if p.Has(n) {
122 return f(n, p.Get(n))
123 }
124 return true
125 })
126}
127
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800128func (p legacyExtensionFields) NewMessage(n pref.FieldNumber) pref.Message {
Damien Neil97e7f572018-12-07 14:28:33 -0800129 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -0700130 if !x.HasType() {
Damien Neil97e7f572018-12-07 14:28:33 -0800131 panic("no extension descriptor registered")
132 }
Joe Tsai89d49632019-06-04 16:20:00 -0700133 xt := x.GetType()
Joe Tsaid18bd312019-01-09 03:23:55 -0800134 return xt.New().Message()
Damien Neil97e7f572018-12-07 14:28:33 -0800135}
136
Joe Tsaif0c01e42018-11-06 13:05:20 -0800137func (p legacyExtensionFields) ExtensionTypes() pref.ExtensionFieldTypes {
138 return legacyExtensionTypes(p)
139}
140
141type legacyExtensionTypes legacyExtensionFields
142
143func (p legacyExtensionTypes) Len() (n int) {
Joe Tsai89d49632019-06-04 16:20:00 -0700144 p.x.Range(func(_ pref.FieldNumber, x ExtensionField) bool {
145 if x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800146 n++
147 }
148 return true
149 })
150 return n
151}
152
153func (p legacyExtensionTypes) Register(t pref.ExtensionType) {
Joe Tsai0fc49f82019-05-01 12:29:25 -0700154 d := t.Descriptor()
Joe Tsaiac31a352019-05-13 14:32:56 -0700155 if p.mi.PBType.Descriptor().FullName() != d.ContainingMessage().FullName() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800156 panic("extended type mismatch")
157 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700158 if !p.mi.PBType.Descriptor().ExtensionRanges().Has(d.Number()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800159 panic("invalid extension field number")
160 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700161 x := p.x.Get(d.Number())
Joe Tsai89d49632019-06-04 16:20:00 -0700162 if x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800163 panic("extension descriptor already registered")
164 }
Joe Tsai89d49632019-06-04 16:20:00 -0700165 x.SetType(t)
Joe Tsaiac31a352019-05-13 14:32:56 -0700166 if d.IsList() {
Joe Tsaif6d4a422018-11-19 14:26:06 -0800167 // If the field is repeated, initialize the entry with an empty list
168 // so that future Get operations can return a mutable and concrete list.
Joe Tsai40b83d62019-05-16 11:45:52 -0700169 x.SetEagerValue(t.InterfaceOf(t.New()))
Joe Tsaif6d4a422018-11-19 14:26:06 -0800170 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700171 p.x.Set(d.Number(), x)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800172}
173
174func (p legacyExtensionTypes) Remove(t pref.ExtensionType) {
Joe Tsai0fc49f82019-05-01 12:29:25 -0700175 d := t.Descriptor()
176 if !p.mi.PBType.Descriptor().ExtensionRanges().Has(d.Number()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800177 return
178 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700179 x := p.x.Get(d.Number())
Joe Tsaiac31a352019-05-13 14:32:56 -0700180 if d.IsList() {
Joe Tsaif6d4a422018-11-19 14:26:06 -0800181 // Treat an empty repeated field as unpopulated.
Joe Tsai40b83d62019-05-16 11:45:52 -0700182 v := reflect.ValueOf(x.GetValue())
183 if !x.HasValue() || v.IsNil() || v.Elem().Len() == 0 {
184 x.SetEagerValue(nil)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800185 }
186 }
Joe Tsai40b83d62019-05-16 11:45:52 -0700187 if x.GetValue() != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800188 panic("value for extension descriptor still populated")
189 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700190 p.x.Clear(d.Number())
Joe Tsaif0c01e42018-11-06 13:05:20 -0800191}
192
193func (p legacyExtensionTypes) ByNumber(n pref.FieldNumber) pref.ExtensionType {
194 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -0700195 if x.HasType() {
196 return x.GetType()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800197 }
198 return nil
199}
200
201func (p legacyExtensionTypes) ByName(s pref.FullName) (t pref.ExtensionType) {
Joe Tsai89d49632019-06-04 16:20:00 -0700202 p.x.Range(func(_ pref.FieldNumber, x ExtensionField) bool {
203 if x.HasType() && x.GetType().FullName() == s {
204 t = x.GetType()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800205 return false
206 }
207 return true
208 })
209 return t
210}
211
212func (p legacyExtensionTypes) Range(f func(pref.ExtensionType) bool) {
Joe Tsai89d49632019-06-04 16:20:00 -0700213 p.x.Range(func(_ pref.FieldNumber, x ExtensionField) bool {
214 if x.HasType() {
215 if !f(x.GetType()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800216 return false
217 }
218 }
219 return true
220 })
221}
Damien Neil4866b952019-03-13 17:36:42 -0700222
Joe Tsai89d49632019-06-04 16:20:00 -0700223type legacyExtensionMap map[int32]ExtensionField
Joe Tsai4fddeba2019-03-20 18:29:32 -0700224
225func (m legacyExtensionMap) Len() int {
226 return len(m)
227}
228func (m legacyExtensionMap) Has(n pref.FieldNumber) bool {
229 _, ok := m[int32(n)]
230 return ok
231}
Joe Tsai89d49632019-06-04 16:20:00 -0700232func (m legacyExtensionMap) Get(n pref.FieldNumber) ExtensionField {
Joe Tsai4fddeba2019-03-20 18:29:32 -0700233 return m[int32(n)]
234}
Joe Tsai89d49632019-06-04 16:20:00 -0700235func (m *legacyExtensionMap) Set(n pref.FieldNumber, x ExtensionField) {
Joe Tsai4fddeba2019-03-20 18:29:32 -0700236 if *m == nil {
Joe Tsai89d49632019-06-04 16:20:00 -0700237 *m = make(map[int32]ExtensionField)
Joe Tsai4fddeba2019-03-20 18:29:32 -0700238 }
239 (*m)[int32(n)] = x
240}
241func (m *legacyExtensionMap) Clear(n pref.FieldNumber) {
242 delete(*m, int32(n))
243}
Joe Tsai89d49632019-06-04 16:20:00 -0700244func (m legacyExtensionMap) Range(f func(pref.FieldNumber, ExtensionField) bool) {
Joe Tsai4fddeba2019-03-20 18:29:32 -0700245 for n, x := range m {
246 if !f(pref.FieldNumber(n), x) {
247 return
248 }
249 }
250}