blob: 00c85737eb3b5c671cbab73f23c6321119815c1a [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
Joe Tsai378c1322019-04-25 23:48:08 -070013// TODO: Remove this file.
14
15var extType = reflect.TypeOf(map[int32]ExtensionField(nil))
16
Joe Tsaif0c01e42018-11-06 13:05:20 -080017func makeLegacyExtensionFieldsFunc(t reflect.Type) func(p *messageDataType) pref.KnownFields {
18 f := makeLegacyExtensionMapFunc(t)
19 if f == nil {
Joe Tsai378c1322019-04-25 23:48:08 -070020 return func(*messageDataType) pref.KnownFields {
21 return emptyExtensionFields{}
22 }
Joe Tsaif0c01e42018-11-06 13:05:20 -080023 }
24 return func(p *messageDataType) pref.KnownFields {
Joe Tsai6cf80c42018-12-01 04:57:09 -080025 if p.p.IsNil() {
26 return emptyExtensionFields{}
27 }
Joe Tsaif0c01e42018-11-06 13:05:20 -080028 return legacyExtensionFields{p.mi, f(p)}
29 }
30}
31
Joe Tsai50c16712019-04-16 01:18:50 -070032func makeLegacyExtensionMapFunc(t reflect.Type) func(*messageDataType) *legacyExtensionMap {
33 fx, _ := t.FieldByName("XXX_extensions")
34 if fx.Type != extType {
35 fx, _ = t.FieldByName("XXX_InternalExtensions")
36 }
37 if fx.Type != extType {
Joe Tsaif18ab532018-11-27 17:25:04 -080038 return nil
39 }
Joe Tsai50c16712019-04-16 01:18:50 -070040
41 fieldOffset := offsetOf(fx)
42 return func(p *messageDataType) *legacyExtensionMap {
43 v := p.p.Apply(fieldOffset).AsValueOf(fx.Type).Interface()
Joe Tsai89d49632019-06-04 16:20:00 -070044 return (*legacyExtensionMap)(v.(*map[int32]ExtensionField))
Joe Tsai50c16712019-04-16 01:18:50 -070045 }
Joe Tsaif18ab532018-11-27 17:25:04 -080046}
47
Joe Tsaif0c01e42018-11-06 13:05:20 -080048type legacyExtensionFields struct {
Joe Tsai4fe96632019-05-22 05:12:36 -040049 mi *MessageInfo
Joe Tsai50c16712019-04-16 01:18:50 -070050 x *legacyExtensionMap
Joe Tsaif0c01e42018-11-06 13:05:20 -080051}
52
53func (p legacyExtensionFields) Len() (n int) {
Joe Tsai89d49632019-06-04 16:20:00 -070054 p.x.Range(func(num pref.FieldNumber, _ ExtensionField) bool {
Joe Tsaif18ab532018-11-27 17:25:04 -080055 if p.Has(pref.FieldNumber(num)) {
Joe Tsaif0c01e42018-11-06 13:05:20 -080056 n++
57 }
58 return true
59 })
60 return n
61}
62
63func (p legacyExtensionFields) Has(n pref.FieldNumber) bool {
64 x := p.x.Get(n)
Joe Tsai40b83d62019-05-16 11:45:52 -070065 if !x.HasValue() {
Joe Tsaif0c01e42018-11-06 13:05:20 -080066 return false
67 }
Joe Tsai89d49632019-06-04 16:20:00 -070068 t := x.GetType()
Joe Tsai0fc49f82019-05-01 12:29:25 -070069 d := t.Descriptor()
Joe Tsaiac31a352019-05-13 14:32:56 -070070 if d.IsList() {
Joe Tsai40b83d62019-05-16 11:45:52 -070071 return t.ValueOf(x.GetValue()).List().Len() > 0
Joe Tsaif0c01e42018-11-06 13:05:20 -080072 }
73 return true
74}
75
76func (p legacyExtensionFields) Get(n pref.FieldNumber) pref.Value {
77 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -070078 if !x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -080079 return pref.Value{}
80 }
Joe Tsai89d49632019-06-04 16:20:00 -070081 t := x.GetType()
Joe Tsai0fc49f82019-05-01 12:29:25 -070082 d := t.Descriptor()
Joe Tsai40b83d62019-05-16 11:45:52 -070083 if !x.HasValue() {
Joe Tsaif18ab532018-11-27 17:25:04 -080084 // 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 Tsai0fc49f82019-05-01 12:29:25 -070086 if d.Kind() == pref.MessageKind || d.Kind() == pref.GroupKind {
Joe Tsaif0c01e42018-11-06 13:05:20 -080087 return pref.Value{}
88 }
Joe Tsai0fc49f82019-05-01 12:29:25 -070089 return d.Default()
Joe Tsaif0c01e42018-11-06 13:05:20 -080090 }
Joe Tsai40b83d62019-05-16 11:45:52 -070091 return t.ValueOf(x.GetValue())
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 Tsai89d49632019-06-04 16:20:00 -070096 if !x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -080097 panic("no extension descriptor registered")
98 }
Joe Tsai89d49632019-06-04 16:20:00 -070099 t := x.GetType()
Joe Tsai40b83d62019-05-16 11:45:52 -0700100 x.SetEagerValue(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 Tsai89d49632019-06-04 16:20:00 -0700106 if !x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800107 return
108 }
Joe Tsai89d49632019-06-04 16:20:00 -0700109 t := x.GetType()
Joe Tsai0fc49f82019-05-01 12:29:25 -0700110 d := t.Descriptor()
Joe Tsaiac31a352019-05-13 14:32:56 -0700111 if d.IsList() {
Joe Tsai40b83d62019-05-16 11:45:52 -0700112 t.ValueOf(x.GetValue()).List().Truncate(0)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800113 return
114 }
Joe Tsai40b83d62019-05-16 11:45:52 -0700115 x.SetEagerValue(nil)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800116 p.x.Set(n, x)
117}
118
Joe Tsai4ec39c72019-04-03 13:40:53 -0700119func (p legacyExtensionFields) WhichOneof(pref.Name) pref.FieldNumber {
120 return 0
121}
122
Joe Tsaif0c01e42018-11-06 13:05:20 -0800123func (p legacyExtensionFields) Range(f func(pref.FieldNumber, pref.Value) bool) {
Joe Tsai89d49632019-06-04 16:20:00 -0700124 p.x.Range(func(n pref.FieldNumber, x ExtensionField) bool {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800125 if p.Has(n) {
126 return f(n, p.Get(n))
127 }
128 return true
129 })
130}
131
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800132func (p legacyExtensionFields) NewMessage(n pref.FieldNumber) pref.Message {
Damien Neil97e7f572018-12-07 14:28:33 -0800133 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -0700134 if !x.HasType() {
Damien Neil97e7f572018-12-07 14:28:33 -0800135 panic("no extension descriptor registered")
136 }
Joe Tsai89d49632019-06-04 16:20:00 -0700137 xt := x.GetType()
Joe Tsaid18bd312019-01-09 03:23:55 -0800138 return xt.New().Message()
Damien Neil97e7f572018-12-07 14:28:33 -0800139}
140
Joe Tsaif0c01e42018-11-06 13:05:20 -0800141func (p legacyExtensionFields) ExtensionTypes() pref.ExtensionFieldTypes {
142 return legacyExtensionTypes(p)
143}
144
145type legacyExtensionTypes legacyExtensionFields
146
147func (p legacyExtensionTypes) Len() (n int) {
Joe Tsai89d49632019-06-04 16:20:00 -0700148 p.x.Range(func(_ pref.FieldNumber, x ExtensionField) bool {
149 if x.HasType() {
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) {
Joe Tsai0fc49f82019-05-01 12:29:25 -0700158 d := t.Descriptor()
Joe Tsaiac31a352019-05-13 14:32:56 -0700159 if p.mi.PBType.Descriptor().FullName() != d.ContainingMessage().FullName() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800160 panic("extended type mismatch")
161 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700162 if !p.mi.PBType.Descriptor().ExtensionRanges().Has(d.Number()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800163 panic("invalid extension field number")
164 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700165 x := p.x.Get(d.Number())
Joe Tsai89d49632019-06-04 16:20:00 -0700166 if x.HasType() {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800167 panic("extension descriptor already registered")
168 }
Joe Tsai89d49632019-06-04 16:20:00 -0700169 x.SetType(t)
Joe Tsaiac31a352019-05-13 14:32:56 -0700170 if d.IsList() {
Joe Tsaif6d4a422018-11-19 14:26:06 -0800171 // If the field is repeated, initialize the entry with an empty list
172 // so that future Get operations can return a mutable and concrete list.
Joe Tsai40b83d62019-05-16 11:45:52 -0700173 x.SetEagerValue(t.InterfaceOf(t.New()))
Joe Tsaif6d4a422018-11-19 14:26:06 -0800174 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700175 p.x.Set(d.Number(), x)
Joe Tsaif0c01e42018-11-06 13:05:20 -0800176}
177
178func (p legacyExtensionTypes) Remove(t pref.ExtensionType) {
Joe Tsai0fc49f82019-05-01 12:29:25 -0700179 d := t.Descriptor()
180 if !p.mi.PBType.Descriptor().ExtensionRanges().Has(d.Number()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800181 return
182 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700183 x := p.x.Get(d.Number())
Joe Tsaiac31a352019-05-13 14:32:56 -0700184 if d.IsList() {
Joe Tsaif6d4a422018-11-19 14:26:06 -0800185 // Treat an empty repeated field as unpopulated.
Joe Tsai40b83d62019-05-16 11:45:52 -0700186 v := reflect.ValueOf(x.GetValue())
187 if !x.HasValue() || v.IsNil() || v.Elem().Len() == 0 {
188 x.SetEagerValue(nil)
Joe Tsaif6d4a422018-11-19 14:26:06 -0800189 }
190 }
Joe Tsai40b83d62019-05-16 11:45:52 -0700191 if x.GetValue() != nil {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800192 panic("value for extension descriptor still populated")
193 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700194 p.x.Clear(d.Number())
Joe Tsaif0c01e42018-11-06 13:05:20 -0800195}
196
197func (p legacyExtensionTypes) ByNumber(n pref.FieldNumber) pref.ExtensionType {
198 x := p.x.Get(n)
Joe Tsai89d49632019-06-04 16:20:00 -0700199 if x.HasType() {
200 return x.GetType()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800201 }
202 return nil
203}
204
205func (p legacyExtensionTypes) ByName(s pref.FullName) (t pref.ExtensionType) {
Joe Tsai89d49632019-06-04 16:20:00 -0700206 p.x.Range(func(_ pref.FieldNumber, x ExtensionField) bool {
207 if x.HasType() && x.GetType().FullName() == s {
208 t = x.GetType()
Joe Tsaif0c01e42018-11-06 13:05:20 -0800209 return false
210 }
211 return true
212 })
213 return t
214}
215
216func (p legacyExtensionTypes) Range(f func(pref.ExtensionType) bool) {
Joe Tsai89d49632019-06-04 16:20:00 -0700217 p.x.Range(func(_ pref.FieldNumber, x ExtensionField) bool {
218 if x.HasType() {
219 if !f(x.GetType()) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800220 return false
221 }
222 }
223 return true
224 })
225}
Damien Neil4866b952019-03-13 17:36:42 -0700226
Joe Tsai89d49632019-06-04 16:20:00 -0700227type legacyExtensionMap map[int32]ExtensionField
Joe Tsai4fddeba2019-03-20 18:29:32 -0700228
229func (m legacyExtensionMap) Len() int {
230 return len(m)
231}
232func (m legacyExtensionMap) Has(n pref.FieldNumber) bool {
233 _, ok := m[int32(n)]
234 return ok
235}
Joe Tsai89d49632019-06-04 16:20:00 -0700236func (m legacyExtensionMap) Get(n pref.FieldNumber) ExtensionField {
Joe Tsai4fddeba2019-03-20 18:29:32 -0700237 return m[int32(n)]
238}
Joe Tsai89d49632019-06-04 16:20:00 -0700239func (m *legacyExtensionMap) Set(n pref.FieldNumber, x ExtensionField) {
Joe Tsai4fddeba2019-03-20 18:29:32 -0700240 if *m == nil {
Joe Tsai89d49632019-06-04 16:20:00 -0700241 *m = make(map[int32]ExtensionField)
Joe Tsai4fddeba2019-03-20 18:29:32 -0700242 }
243 (*m)[int32(n)] = x
244}
245func (m *legacyExtensionMap) Clear(n pref.FieldNumber) {
246 delete(*m, int32(n))
247}
Joe Tsai89d49632019-06-04 16:20:00 -0700248func (m legacyExtensionMap) Range(f func(pref.FieldNumber, ExtensionField) bool) {
Joe Tsai4fddeba2019-03-20 18:29:32 -0700249 for n, x := range m {
250 if !f(pref.FieldNumber(n), x) {
251 return
252 }
253 }
254}