blob: 997f57c1e1027f1f7051b528f91f35f16e9a0428 [file] [log] [blame]
divyadesai81bb7ba2020-03-11 11:45:23 +00001// Protocol Buffers for Go with Gadgets
2//
3// Copyright (c) 2018, The GoGo Authors. All rights reserved.
4// http://github.com/gogo/protobuf
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29package proto
30
31import (
32 "reflect"
33 "time"
34)
35
36// makeMessageRefMarshaler differs a bit from makeMessageMarshaler
37// It marshal a message T instead of a *T
38func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) {
39 return func(ptr pointer, tagsize int) int {
40 siz := u.size(ptr)
41 return siz + SizeVarint(uint64(siz)) + tagsize
42 },
43 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
44 b = appendVarint(b, wiretag)
45 siz := u.cachedsize(ptr)
46 b = appendVarint(b, uint64(siz))
47 return u.marshal(b, ptr, deterministic)
48 }
49}
50
51// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler
52// It marshals a slice of messages []T instead of []*T
53func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
54 return func(ptr pointer, tagsize int) int {
55 s := ptr.getSlice(u.typ)
56 n := 0
57 for i := 0; i < s.Len(); i++ {
58 elem := s.Index(i)
59 e := elem.Interface()
60 v := toAddrPointer(&e, false)
61 siz := u.size(v)
62 n += siz + SizeVarint(uint64(siz)) + tagsize
63 }
64 return n
65 },
66 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
67 s := ptr.getSlice(u.typ)
68 var err, errreq error
69 for i := 0; i < s.Len(); i++ {
70 elem := s.Index(i)
71 e := elem.Interface()
72 v := toAddrPointer(&e, false)
73 b = appendVarint(b, wiretag)
74 siz := u.size(v)
75 b = appendVarint(b, uint64(siz))
76 b, err = u.marshal(b, v, deterministic)
77
78 if err != nil {
79 if _, ok := err.(*RequiredNotSetError); ok {
80 // Required field in submessage is not set.
81 // We record the error but keep going, to give a complete marshaling.
82 if errreq == nil {
83 errreq = err
84 }
85 continue
86 }
87 if err == ErrNil {
88 err = errRepeatedHasNil
89 }
90 return b, err
91 }
92 }
93
94 return b, errreq
95 }
96}
97
98func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
99 return func(ptr pointer, tagsize int) int {
100 if ptr.isNil() {
101 return 0
102 }
103 m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
104 siz := m.Size()
105 return tagsize + SizeVarint(uint64(siz)) + siz
106 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
107 if ptr.isNil() {
108 return b, nil
109 }
110 m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
111 siz := m.Size()
112 buf, err := m.Marshal()
113 if err != nil {
114 return nil, err
115 }
116 b = appendVarint(b, wiretag)
117 b = appendVarint(b, uint64(siz))
118 b = append(b, buf...)
119 return b, nil
120 }
121}
122
123func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) {
124 return func(ptr pointer, tagsize int) int {
125 m := ptr.asPointerTo(u.typ).Interface().(custom)
126 siz := m.Size()
127 return tagsize + SizeVarint(uint64(siz)) + siz
128 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
129 m := ptr.asPointerTo(u.typ).Interface().(custom)
130 siz := m.Size()
131 buf, err := m.Marshal()
132 if err != nil {
133 return nil, err
134 }
135 b = appendVarint(b, wiretag)
136 b = appendVarint(b, uint64(siz))
137 b = append(b, buf...)
138 return b, nil
139 }
140}
141
142func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) {
143 return func(ptr pointer, tagsize int) int {
144 t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
145 ts, err := timestampProto(*t)
146 if err != nil {
147 return 0
148 }
149 siz := Size(ts)
150 return tagsize + SizeVarint(uint64(siz)) + siz
151 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
152 t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
153 ts, err := timestampProto(*t)
154 if err != nil {
155 return nil, err
156 }
157 buf, err := Marshal(ts)
158 if err != nil {
159 return nil, err
160 }
161 b = appendVarint(b, wiretag)
162 b = appendVarint(b, uint64(len(buf)))
163 b = append(b, buf...)
164 return b, nil
165 }
166}
167
168func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
169 return func(ptr pointer, tagsize int) int {
170 if ptr.isNil() {
171 return 0
172 }
173 t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
174 ts, err := timestampProto(*t)
175 if err != nil {
176 return 0
177 }
178 siz := Size(ts)
179 return tagsize + SizeVarint(uint64(siz)) + siz
180 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
181 if ptr.isNil() {
182 return b, nil
183 }
184 t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
185 ts, err := timestampProto(*t)
186 if err != nil {
187 return nil, err
188 }
189 buf, err := Marshal(ts)
190 if err != nil {
191 return nil, err
192 }
193 b = appendVarint(b, wiretag)
194 b = appendVarint(b, uint64(len(buf)))
195 b = append(b, buf...)
196 return b, nil
197 }
198}
199
200func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
201 return func(ptr pointer, tagsize int) int {
202 s := ptr.getSlice(u.typ)
203 n := 0
204 for i := 0; i < s.Len(); i++ {
205 elem := s.Index(i)
206 t := elem.Interface().(time.Time)
207 ts, err := timestampProto(t)
208 if err != nil {
209 return 0
210 }
211 siz := Size(ts)
212 n += siz + SizeVarint(uint64(siz)) + tagsize
213 }
214 return n
215 },
216 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
217 s := ptr.getSlice(u.typ)
218 for i := 0; i < s.Len(); i++ {
219 elem := s.Index(i)
220 t := elem.Interface().(time.Time)
221 ts, err := timestampProto(t)
222 if err != nil {
223 return nil, err
224 }
225 siz := Size(ts)
226 buf, err := Marshal(ts)
227 if err != nil {
228 return nil, err
229 }
230 b = appendVarint(b, wiretag)
231 b = appendVarint(b, uint64(siz))
232 b = append(b, buf...)
233 }
234
235 return b, nil
236 }
237}
238
239func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
240 return func(ptr pointer, tagsize int) int {
241 s := ptr.getSlice(reflect.PtrTo(u.typ))
242 n := 0
243 for i := 0; i < s.Len(); i++ {
244 elem := s.Index(i)
245 t := elem.Interface().(*time.Time)
246 ts, err := timestampProto(*t)
247 if err != nil {
248 return 0
249 }
250 siz := Size(ts)
251 n += siz + SizeVarint(uint64(siz)) + tagsize
252 }
253 return n
254 },
255 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
256 s := ptr.getSlice(reflect.PtrTo(u.typ))
257 for i := 0; i < s.Len(); i++ {
258 elem := s.Index(i)
259 t := elem.Interface().(*time.Time)
260 ts, err := timestampProto(*t)
261 if err != nil {
262 return nil, err
263 }
264 siz := Size(ts)
265 buf, err := Marshal(ts)
266 if err != nil {
267 return nil, err
268 }
269 b = appendVarint(b, wiretag)
270 b = appendVarint(b, uint64(siz))
271 b = append(b, buf...)
272 }
273
274 return b, nil
275 }
276}
277
278func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) {
279 return func(ptr pointer, tagsize int) int {
280 d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
281 dur := durationProto(*d)
282 siz := Size(dur)
283 return tagsize + SizeVarint(uint64(siz)) + siz
284 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
285 d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
286 dur := durationProto(*d)
287 buf, err := Marshal(dur)
288 if err != nil {
289 return nil, err
290 }
291 b = appendVarint(b, wiretag)
292 b = appendVarint(b, uint64(len(buf)))
293 b = append(b, buf...)
294 return b, nil
295 }
296}
297
298func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
299 return func(ptr pointer, tagsize int) int {
300 if ptr.isNil() {
301 return 0
302 }
303 d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
304 dur := durationProto(*d)
305 siz := Size(dur)
306 return tagsize + SizeVarint(uint64(siz)) + siz
307 }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
308 if ptr.isNil() {
309 return b, nil
310 }
311 d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
312 dur := durationProto(*d)
313 buf, err := Marshal(dur)
314 if err != nil {
315 return nil, err
316 }
317 b = appendVarint(b, wiretag)
318 b = appendVarint(b, uint64(len(buf)))
319 b = append(b, buf...)
320 return b, nil
321 }
322}
323
324func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
325 return func(ptr pointer, tagsize int) int {
326 s := ptr.getSlice(u.typ)
327 n := 0
328 for i := 0; i < s.Len(); i++ {
329 elem := s.Index(i)
330 d := elem.Interface().(time.Duration)
331 dur := durationProto(d)
332 siz := Size(dur)
333 n += siz + SizeVarint(uint64(siz)) + tagsize
334 }
335 return n
336 },
337 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
338 s := ptr.getSlice(u.typ)
339 for i := 0; i < s.Len(); i++ {
340 elem := s.Index(i)
341 d := elem.Interface().(time.Duration)
342 dur := durationProto(d)
343 siz := Size(dur)
344 buf, err := Marshal(dur)
345 if err != nil {
346 return nil, err
347 }
348 b = appendVarint(b, wiretag)
349 b = appendVarint(b, uint64(siz))
350 b = append(b, buf...)
351 }
352
353 return b, nil
354 }
355}
356
357func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
358 return func(ptr pointer, tagsize int) int {
359 s := ptr.getSlice(reflect.PtrTo(u.typ))
360 n := 0
361 for i := 0; i < s.Len(); i++ {
362 elem := s.Index(i)
363 d := elem.Interface().(*time.Duration)
364 dur := durationProto(*d)
365 siz := Size(dur)
366 n += siz + SizeVarint(uint64(siz)) + tagsize
367 }
368 return n
369 },
370 func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
371 s := ptr.getSlice(reflect.PtrTo(u.typ))
372 for i := 0; i < s.Len(); i++ {
373 elem := s.Index(i)
374 d := elem.Interface().(*time.Duration)
375 dur := durationProto(*d)
376 siz := Size(dur)
377 buf, err := Marshal(dur)
378 if err != nil {
379 return nil, err
380 }
381 b = appendVarint(b, wiretag)
382 b = appendVarint(b, uint64(siz))
383 b = append(b, buf...)
384 }
385
386 return b, nil
387 }
388}