blob: 1512d605b2dd0c0e54a1288be9b9a7ec9ca57fce [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// Go support for Protocol Buffers - Google's data interchange format
2//
David Symondsee6e9c52012-11-29 08:51:07 +11003// Copyright 2010 The Go Authors. All rights reserved.
David Symonds558f13f2014-11-24 10:28:53 +11004// https://github.com/golang/protobuf
Rob Pikeaaa3a622010-03-20 22:32:34 -07005//
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// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32package proto
33
34/*
35 * Routines for encoding data into the wire format for protocol buffers.
36 */
37
38import (
Rob Pikea17fdd92011-11-02 12:43:05 -070039 "errors"
David Symonds4646c372013-09-09 13:18:58 +100040 "fmt"
Rob Pikeaaa3a622010-03-20 22:32:34 -070041 "reflect"
David Symondsdf583ae2012-12-06 14:06:53 +110042 "sort"
Rob Pikeaaa3a622010-03-20 22:32:34 -070043)
44
David Symondse583a5f2013-09-27 10:02:37 +100045// RequiredNotSetError is the error returned if Marshal is called with
Rob Pikeaaa3a622010-03-20 22:32:34 -070046// a protocol buffer struct whose required fields have not
Rob Pikec6d8e4a2010-07-28 15:34:32 -070047// all been initialized. It is also the error returned if Unmarshal is
48// called with an encoded protocol buffer that does not include all the
49// required fields.
David Symonds4646c372013-09-09 13:18:58 +100050//
David Symondse583a5f2013-09-27 10:02:37 +100051// When printed, RequiredNotSetError reports the first unset required field in a
David Symonds4646c372013-09-09 13:18:58 +100052// message. If the field cannot be precisely determined, it is reported as
53// "{Unknown}".
David Symondse583a5f2013-09-27 10:02:37 +100054type RequiredNotSetError struct {
David Symonds4646c372013-09-09 13:18:58 +100055 field string
David Symonds5b7775e2010-12-01 10:09:04 +110056}
57
David Symondse583a5f2013-09-27 10:02:37 +100058func (e *RequiredNotSetError) Error() string {
David Symonds4646c372013-09-09 13:18:58 +100059 return fmt.Sprintf("proto: required field %q not set", e.field)
David Symonds5b7775e2010-12-01 10:09:04 +110060}
Rob Pikeaaa3a622010-03-20 22:32:34 -070061
David Symonds7656e742011-07-22 14:54:17 +100062var (
63 // ErrRepeatedHasNil is the error returned if Marshal is called with
64 // a struct with a repeated field containing a nil element.
David Symonds381349d2012-09-18 15:11:46 +100065 ErrRepeatedHasNil = errors.New("proto: repeated field has nil element")
Rob Pikeaaa3a622010-03-20 22:32:34 -070066
David Symonds7656e742011-07-22 14:54:17 +100067 // ErrNil is the error returned if Marshal is called with nil.
Rob Pikea17fdd92011-11-02 12:43:05 -070068 ErrNil = errors.New("proto: Marshal called with nil")
David Symonds7656e742011-07-22 14:54:17 +100069)
Rob Pikeaaa3a622010-03-20 22:32:34 -070070
71// The fundamental encoders that put bytes on the wire.
72// Those that take integer types all accept uint64 and are
73// therefore of type valueEncoder.
74
David Symonds4fee3b12010-11-11 10:00:13 +110075const maxVarintBytes = 10 // maximum length of a varint
76
Rob Pikeaaa3a622010-03-20 22:32:34 -070077// EncodeVarint returns the varint encoding of x.
78// This is the format for the
79// int32, int64, uint32, uint64, bool, and enum
80// protocol buffer types.
81// Not used by the package itself, but helpful to clients
82// wishing to use the same encoding.
83func EncodeVarint(x uint64) []byte {
David Symonds4fee3b12010-11-11 10:00:13 +110084 var buf [maxVarintBytes]byte
Rob Pikeaaa3a622010-03-20 22:32:34 -070085 var n int
86 for n = 0; x > 127; n++ {
87 buf[n] = 0x80 | uint8(x&0x7F)
88 x >>= 7
89 }
90 buf[n] = uint8(x)
91 n++
92 return buf[0:n]
93}
94
95// EncodeVarint writes a varint-encoded integer to the Buffer.
96// This is the format for the
97// int32, int64, uint32, uint64, bool, and enum
98// protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -070099func (p *Buffer) EncodeVarint(x uint64) error {
David Symonds4fee3b12010-11-11 10:00:13 +1100100 for x >= 1<<7 {
David Symondsd9da6ba2011-08-30 14:41:30 +1000101 p.buf = append(p.buf, uint8(x&0x7f|0x80))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700102 x >>= 7
103 }
David Symondsd9da6ba2011-08-30 14:41:30 +1000104 p.buf = append(p.buf, uint8(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700105 return nil
106}
107
David Symonds0bf1ad52013-10-11 09:07:50 +1100108func sizeVarint(x uint64) (n int) {
109 for {
110 n++
111 x >>= 7
112 if x == 0 {
113 break
114 }
115 }
116 return n
117}
118
Rob Pikeaaa3a622010-03-20 22:32:34 -0700119// EncodeFixed64 writes a 64-bit integer to the Buffer.
120// This is the format for the
121// fixed64, sfixed64, and double protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700122func (p *Buffer) EncodeFixed64(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000123 p.buf = append(p.buf,
124 uint8(x),
125 uint8(x>>8),
126 uint8(x>>16),
127 uint8(x>>24),
128 uint8(x>>32),
129 uint8(x>>40),
130 uint8(x>>48),
131 uint8(x>>56))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700132 return nil
133}
134
David Symonds0bf1ad52013-10-11 09:07:50 +1100135func sizeFixed64(x uint64) int {
136 return 8
137}
138
Rob Pikeaaa3a622010-03-20 22:32:34 -0700139// EncodeFixed32 writes a 32-bit integer to the Buffer.
140// This is the format for the
141// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700142func (p *Buffer) EncodeFixed32(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000143 p.buf = append(p.buf,
144 uint8(x),
145 uint8(x>>8),
146 uint8(x>>16),
147 uint8(x>>24))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700148 return nil
149}
150
David Symonds0bf1ad52013-10-11 09:07:50 +1100151func sizeFixed32(x uint64) int {
152 return 4
153}
154
Rob Pikeaaa3a622010-03-20 22:32:34 -0700155// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
156// to the Buffer.
157// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700158func (p *Buffer) EncodeZigzag64(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700159 // use signed number to get arithmetic right shift.
160 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
161}
162
David Symonds0bf1ad52013-10-11 09:07:50 +1100163func sizeZigzag64(x uint64) int {
164 return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
165}
166
Rob Pikeaaa3a622010-03-20 22:32:34 -0700167// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
168// to the Buffer.
169// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700170func (p *Buffer) EncodeZigzag32(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700171 // use signed number to get arithmetic right shift.
172 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
173}
174
David Symonds0bf1ad52013-10-11 09:07:50 +1100175func sizeZigzag32(x uint64) int {
176 return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
177}
178
Rob Pikeaaa3a622010-03-20 22:32:34 -0700179// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
180// This is the format used for the bytes protocol buffer
181// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700182func (p *Buffer) EncodeRawBytes(b []byte) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700183 p.EncodeVarint(uint64(len(b)))
Rob Pike99fa2b62010-12-02 10:39:42 -0800184 p.buf = append(p.buf, b...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700185 return nil
186}
187
David Symonds0bf1ad52013-10-11 09:07:50 +1100188func sizeRawBytes(b []byte) int {
189 return sizeVarint(uint64(len(b))) +
190 len(b)
191}
192
Rob Pikeaaa3a622010-03-20 22:32:34 -0700193// EncodeStringBytes writes an encoded string to the Buffer.
194// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700195func (p *Buffer) EncodeStringBytes(s string) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700196 p.EncodeVarint(uint64(len(s)))
197 p.buf = append(p.buf, s...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700198 return nil
199}
200
David Symonds0bf1ad52013-10-11 09:07:50 +1100201func sizeStringBytes(s string) int {
202 return sizeVarint(uint64(len(s))) +
203 len(s)
204}
205
Rob Pikeaaa3a622010-03-20 22:32:34 -0700206// Marshaler is the interface representing objects that can marshal themselves.
207type Marshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700208 Marshal() ([]byte, error)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700209}
210
David Symonds9f60f432012-06-14 09:45:25 +1000211// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700212// and encodes it into the wire format, returning the data.
David Symonds9f60f432012-06-14 09:45:25 +1000213func Marshal(pb Message) ([]byte, error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700214 // Can the object marshal itself?
215 if m, ok := pb.(Marshaler); ok {
216 return m.Marshal()
217 }
218 p := NewBuffer(nil)
219 err := p.Marshal(pb)
David Symonds4646c372013-09-09 13:18:58 +1000220 var state errorState
221 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700222 return nil, err
223 }
David Symonds8b253302014-01-14 16:24:19 +1100224 if p.buf == nil && err == nil {
225 // Return a non-nil slice on success.
226 return []byte{}, nil
227 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700228 return p.buf, err
229}
230
David Symonds9f60f432012-06-14 09:45:25 +1000231// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700232// and encodes it into the wire format, writing the result to the
233// Buffer.
David Symonds9f60f432012-06-14 09:45:25 +1000234func (p *Buffer) Marshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700235 // Can the object marshal itself?
236 if m, ok := pb.(Marshaler); ok {
237 data, err := m.Marshal()
238 if err != nil {
239 return err
240 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800241 p.buf = append(p.buf, data...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700242 return nil
243 }
244
Russ Coxd4ce3f12012-09-12 10:36:26 +1000245 t, base, err := getbase(pb)
246 if structPointer_IsNil(base) {
David Symondsd4661c52012-08-30 15:17:53 +1000247 return ErrNil
248 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700249 if err == nil {
David Symondsba7896c2014-11-20 15:29:05 +1100250 err = p.enc_struct(GetProperties(t.Elem()), base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700251 }
252
David Symonds9f60f432012-06-14 09:45:25 +1000253 if collectStats {
254 stats.Encode++
255 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700256
257 return err
258}
259
David Symonds0bf1ad52013-10-11 09:07:50 +1100260// Size returns the encoded size of a protocol buffer.
261func Size(pb Message) (n int) {
262 // Can the object marshal itself? If so, Size is slow.
263 // TODO: add Size to Marshaler, or add a Sizer interface.
264 if m, ok := pb.(Marshaler); ok {
265 b, _ := m.Marshal()
266 return len(b)
267 }
268
269 t, base, err := getbase(pb)
270 if structPointer_IsNil(base) {
271 return 0
272 }
273 if err == nil {
David Symondsba7896c2014-11-20 15:29:05 +1100274 n = size_struct(GetProperties(t.Elem()), base)
David Symonds0bf1ad52013-10-11 09:07:50 +1100275 }
276
277 if collectStats {
278 stats.Size++
279 }
280
281 return
282}
283
Rob Pikeaaa3a622010-03-20 22:32:34 -0700284// Individual type encoders.
285
286// Encode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000287func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
288 v := *structPointer_Bool(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700289 if v == nil {
290 return ErrNil
291 }
Rob Pike0f42a272011-10-20 16:03:11 -0700292 x := 0
293 if *v {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700294 x = 1
295 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800296 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700297 p.valEnc(o, uint64(x))
298 return nil
299}
300
David Symondsabd3b412014-11-28 11:43:44 +1100301func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
302 v := *structPointer_BoolVal(base, p.field)
303 if !v {
304 return ErrNil
305 }
306 o.buf = append(o.buf, p.tagcode...)
307 p.valEnc(o, 1)
308 return nil
309}
310
David Symonds0bf1ad52013-10-11 09:07:50 +1100311func size_bool(p *Properties, base structPointer) int {
312 v := *structPointer_Bool(base, p.field)
313 if v == nil {
314 return 0
315 }
316 return len(p.tagcode) + 1 // each bool takes exactly one byte
317}
318
David Symondsabd3b412014-11-28 11:43:44 +1100319func size_proto3_bool(p *Properties, base structPointer) int {
320 v := *structPointer_BoolVal(base, p.field)
321 if !v {
322 return 0
323 }
324 return len(p.tagcode) + 1 // each bool takes exactly one byte
325}
326
Rob Pikeaaa3a622010-03-20 22:32:34 -0700327// Encode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000328func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
329 v := structPointer_Word32(base, p.field)
330 if word32_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700331 return ErrNil
332 }
David Symondsf054e842014-07-22 14:06:27 +1000333 x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
Rob Pike99fa2b62010-12-02 10:39:42 -0800334 o.buf = append(o.buf, p.tagcode...)
David Symondsc31645c2013-06-22 17:57:36 +1000335 p.valEnc(o, uint64(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700336 return nil
337}
338
David Symondsabd3b412014-11-28 11:43:44 +1100339func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
340 v := structPointer_Word32Val(base, p.field)
341 x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
342 if x == 0 {
343 return ErrNil
344 }
345 o.buf = append(o.buf, p.tagcode...)
346 p.valEnc(o, uint64(x))
347 return nil
348}
349
David Symonds0bf1ad52013-10-11 09:07:50 +1100350func size_int32(p *Properties, base structPointer) (n int) {
351 v := structPointer_Word32(base, p.field)
352 if word32_IsNil(v) {
353 return 0
354 }
David Symondsf054e842014-07-22 14:06:27 +1000355 x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
356 n += len(p.tagcode)
357 n += p.valSize(uint64(x))
358 return
359}
360
David Symondsabd3b412014-11-28 11:43:44 +1100361func size_proto3_int32(p *Properties, base structPointer) (n int) {
362 v := structPointer_Word32Val(base, p.field)
363 x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
364 if x == 0 {
365 return 0
366 }
367 n += len(p.tagcode)
368 n += p.valSize(uint64(x))
369 return
370}
371
David Symondsf054e842014-07-22 14:06:27 +1000372// Encode a uint32.
373// Exactly the same as int32, except for no sign extension.
374func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
375 v := structPointer_Word32(base, p.field)
376 if word32_IsNil(v) {
377 return ErrNil
378 }
379 x := word32_Get(v)
380 o.buf = append(o.buf, p.tagcode...)
381 p.valEnc(o, uint64(x))
382 return nil
383}
384
David Symondsabd3b412014-11-28 11:43:44 +1100385func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
386 v := structPointer_Word32Val(base, p.field)
387 x := word32Val_Get(v)
388 if x == 0 {
389 return ErrNil
390 }
391 o.buf = append(o.buf, p.tagcode...)
392 p.valEnc(o, uint64(x))
393 return nil
394}
395
David Symondsf054e842014-07-22 14:06:27 +1000396func size_uint32(p *Properties, base structPointer) (n int) {
397 v := structPointer_Word32(base, p.field)
398 if word32_IsNil(v) {
399 return 0
400 }
David Symonds0bf1ad52013-10-11 09:07:50 +1100401 x := word32_Get(v)
402 n += len(p.tagcode)
403 n += p.valSize(uint64(x))
404 return
405}
406
David Symondsabd3b412014-11-28 11:43:44 +1100407func size_proto3_uint32(p *Properties, base structPointer) (n int) {
408 v := structPointer_Word32Val(base, p.field)
409 x := word32Val_Get(v)
410 if x == 0 {
411 return 0
412 }
413 n += len(p.tagcode)
414 n += p.valSize(uint64(x))
415 return
416}
417
Rob Pikeaaa3a622010-03-20 22:32:34 -0700418// Encode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000419func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
420 v := structPointer_Word64(base, p.field)
421 if word64_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700422 return ErrNil
423 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000424 x := word64_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800425 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000426 p.valEnc(o, x)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700427 return nil
428}
429
David Symondsabd3b412014-11-28 11:43:44 +1100430func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
431 v := structPointer_Word64Val(base, p.field)
432 x := word64Val_Get(v)
433 if x == 0 {
434 return ErrNil
435 }
436 o.buf = append(o.buf, p.tagcode...)
437 p.valEnc(o, x)
438 return nil
439}
440
David Symonds0bf1ad52013-10-11 09:07:50 +1100441func size_int64(p *Properties, base structPointer) (n int) {
442 v := structPointer_Word64(base, p.field)
443 if word64_IsNil(v) {
444 return 0
445 }
446 x := word64_Get(v)
447 n += len(p.tagcode)
448 n += p.valSize(x)
449 return
450}
451
David Symondsabd3b412014-11-28 11:43:44 +1100452func size_proto3_int64(p *Properties, base structPointer) (n int) {
453 v := structPointer_Word64Val(base, p.field)
454 x := word64Val_Get(v)
455 if x == 0 {
456 return 0
457 }
458 n += len(p.tagcode)
459 n += p.valSize(x)
460 return
461}
462
Rob Pikeaaa3a622010-03-20 22:32:34 -0700463// Encode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000464func (o *Buffer) enc_string(p *Properties, base structPointer) error {
465 v := *structPointer_String(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700466 if v == nil {
467 return ErrNil
468 }
469 x := *v
Rob Pike99fa2b62010-12-02 10:39:42 -0800470 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700471 o.EncodeStringBytes(x)
472 return nil
473}
474
David Symondsabd3b412014-11-28 11:43:44 +1100475func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
476 v := *structPointer_StringVal(base, p.field)
477 if v == "" {
478 return ErrNil
479 }
480 o.buf = append(o.buf, p.tagcode...)
481 o.EncodeStringBytes(v)
482 return nil
483}
484
David Symonds0bf1ad52013-10-11 09:07:50 +1100485func size_string(p *Properties, base structPointer) (n int) {
486 v := *structPointer_String(base, p.field)
487 if v == nil {
488 return 0
489 }
490 x := *v
491 n += len(p.tagcode)
492 n += sizeStringBytes(x)
493 return
494}
495
David Symondsabd3b412014-11-28 11:43:44 +1100496func size_proto3_string(p *Properties, base structPointer) (n int) {
497 v := *structPointer_StringVal(base, p.field)
498 if v == "" {
499 return 0
500 }
501 n += len(p.tagcode)
502 n += sizeStringBytes(v)
503 return
504}
505
Rob Pike97e934d2011-04-11 12:52:49 -0700506// All protocol buffer fields are nillable, but be careful.
507func isNil(v reflect.Value) bool {
508 switch v.Kind() {
David Symonds007ed9d2012-07-24 10:59:36 +1000509 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
Rob Pike97e934d2011-04-11 12:52:49 -0700510 return v.IsNil()
511 }
512 return false
513}
514
Rob Pikeaaa3a622010-03-20 22:32:34 -0700515// Encode a message struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000516func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000517 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000518 structp := structPointer_GetStructPointer(base, p.field)
519 if structPointer_IsNil(structp) {
David Symondsa80b2822012-03-14 14:31:25 +1100520 return ErrNil
521 }
522
Rob Pikeaaa3a622010-03-20 22:32:34 -0700523 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100524 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000525 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700526 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000527 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700528 return err
529 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800530 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700531 o.EncodeRawBytes(data)
532 return nil
533 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700534
Rob Pike99fa2b62010-12-02 10:39:42 -0800535 o.buf = append(o.buf, p.tagcode...)
David Symondsba7896c2014-11-20 15:29:05 +1100536 return o.enc_len_struct(p.sprop, structp, &state)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700537}
538
David Symonds0bf1ad52013-10-11 09:07:50 +1100539func size_struct_message(p *Properties, base structPointer) int {
540 structp := structPointer_GetStructPointer(base, p.field)
541 if structPointer_IsNil(structp) {
542 return 0
543 }
544
545 // Can the object marshal itself?
546 if p.isMarshaler {
547 m := structPointer_Interface(structp, p.stype).(Marshaler)
548 data, _ := m.Marshal()
549 n0 := len(p.tagcode)
550 n1 := sizeRawBytes(data)
551 return n0 + n1
552 }
553
554 n0 := len(p.tagcode)
David Symondsba7896c2014-11-20 15:29:05 +1100555 n1 := size_struct(p.sprop, structp)
David Symonds0bf1ad52013-10-11 09:07:50 +1100556 n2 := sizeVarint(uint64(n1)) // size of encoded length
557 return n0 + n1 + n2
558}
559
Rob Pikeaaa3a622010-03-20 22:32:34 -0700560// Encode a group struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000561func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000562 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000563 b := structPointer_GetStructPointer(base, p.field)
564 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700565 return ErrNil
566 }
567
568 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symondsba7896c2014-11-20 15:29:05 +1100569 err := o.enc_struct(p.sprop, b)
David Symonds4646c372013-09-09 13:18:58 +1000570 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700571 return err
572 }
573 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
David Symonds4646c372013-09-09 13:18:58 +1000574 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700575}
576
David Symonds0bf1ad52013-10-11 09:07:50 +1100577func size_struct_group(p *Properties, base structPointer) (n int) {
578 b := structPointer_GetStructPointer(base, p.field)
579 if structPointer_IsNil(b) {
580 return 0
581 }
582
583 n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symondsba7896c2014-11-20 15:29:05 +1100584 n += size_struct(p.sprop, b)
David Symonds0bf1ad52013-10-11 09:07:50 +1100585 n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
586 return
587}
588
Rob Pikeaaa3a622010-03-20 22:32:34 -0700589// Encode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000590func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
591 s := *structPointer_BoolSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700592 l := len(s)
593 if l == 0 {
594 return ErrNil
595 }
596 for _, x := range s {
Rob Pike99fa2b62010-12-02 10:39:42 -0800597 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000598 v := uint64(0)
599 if x {
600 v = 1
Rob Pikeaaa3a622010-03-20 22:32:34 -0700601 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000602 p.valEnc(o, v)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700603 }
604 return nil
605}
606
David Symonds0bf1ad52013-10-11 09:07:50 +1100607func size_slice_bool(p *Properties, base structPointer) int {
608 s := *structPointer_BoolSlice(base, p.field)
609 l := len(s)
610 if l == 0 {
611 return 0
612 }
613 return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
614}
615
David Symonds5b7775e2010-12-01 10:09:04 +1100616// Encode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000617func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
618 s := *structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100619 l := len(s)
620 if l == 0 {
621 return ErrNil
622 }
623 o.buf = append(o.buf, p.tagcode...)
624 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
625 for _, x := range s {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000626 v := uint64(0)
627 if x {
628 v = 1
David Symonds5b7775e2010-12-01 10:09:04 +1100629 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000630 p.valEnc(o, v)
David Symonds5b7775e2010-12-01 10:09:04 +1100631 }
632 return nil
633}
634
David Symonds0bf1ad52013-10-11 09:07:50 +1100635func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
636 s := *structPointer_BoolSlice(base, p.field)
637 l := len(s)
638 if l == 0 {
639 return 0
640 }
641 n += len(p.tagcode)
642 n += sizeVarint(uint64(l))
643 n += l // each bool takes exactly one byte
644 return
645}
646
Rob Pikeaaa3a622010-03-20 22:32:34 -0700647// Encode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000648func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
649 s := *structPointer_Bytes(base, p.field)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800650 if s == nil {
651 return ErrNil
652 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800653 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700654 o.EncodeRawBytes(s)
655 return nil
656}
657
David Symondsabd3b412014-11-28 11:43:44 +1100658func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
659 s := *structPointer_Bytes(base, p.field)
660 if len(s) == 0 {
661 return ErrNil
662 }
663 o.buf = append(o.buf, p.tagcode...)
664 o.EncodeRawBytes(s)
665 return nil
666}
667
David Symonds0bf1ad52013-10-11 09:07:50 +1100668func size_slice_byte(p *Properties, base structPointer) (n int) {
669 s := *structPointer_Bytes(base, p.field)
670 if s == nil {
671 return 0
672 }
673 n += len(p.tagcode)
674 n += sizeRawBytes(s)
675 return
676}
677
David Symondsabd3b412014-11-28 11:43:44 +1100678func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
679 s := *structPointer_Bytes(base, p.field)
680 if len(s) == 0 {
681 return 0
682 }
683 n += len(p.tagcode)
684 n += sizeRawBytes(s)
685 return
686}
687
Rob Pikeaaa3a622010-03-20 22:32:34 -0700688// Encode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000689func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
690 s := structPointer_Word32Slice(base, p.field)
691 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700692 if l == 0 {
693 return ErrNil
694 }
695 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800696 o.buf = append(o.buf, p.tagcode...)
David Symonds0ec36a22014-08-12 13:21:46 +1000697 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
Rob Pikeaaa3a622010-03-20 22:32:34 -0700698 p.valEnc(o, uint64(x))
699 }
700 return nil
701}
702
David Symonds0bf1ad52013-10-11 09:07:50 +1100703func size_slice_int32(p *Properties, base structPointer) (n int) {
704 s := structPointer_Word32Slice(base, p.field)
705 l := s.Len()
706 if l == 0 {
707 return 0
708 }
709 for i := 0; i < l; i++ {
710 n += len(p.tagcode)
David Symonds0ec36a22014-08-12 13:21:46 +1000711 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
David Symonds0bf1ad52013-10-11 09:07:50 +1100712 n += p.valSize(uint64(x))
713 }
714 return
715}
716
David Symonds5b7775e2010-12-01 10:09:04 +1100717// Encode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000718func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
719 s := structPointer_Word32Slice(base, p.field)
720 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100721 if l == 0 {
722 return ErrNil
723 }
724 // TODO: Reuse a Buffer.
725 buf := NewBuffer(nil)
726 for i := 0; i < l; i++ {
David Symonds0ec36a22014-08-12 13:21:46 +1000727 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
728 p.valEnc(buf, uint64(x))
729 }
730
731 o.buf = append(o.buf, p.tagcode...)
732 o.EncodeVarint(uint64(len(buf.buf)))
733 o.buf = append(o.buf, buf.buf...)
734 return nil
735}
736
737func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
738 s := structPointer_Word32Slice(base, p.field)
739 l := s.Len()
740 if l == 0 {
741 return 0
742 }
743 var bufSize int
744 for i := 0; i < l; i++ {
745 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
746 bufSize += p.valSize(uint64(x))
747 }
748
749 n += len(p.tagcode)
750 n += sizeVarint(uint64(bufSize))
751 n += bufSize
752 return
753}
754
755// Encode a slice of uint32s ([]uint32).
756// Exactly the same as int32, except for no sign extension.
757func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
758 s := structPointer_Word32Slice(base, p.field)
759 l := s.Len()
760 if l == 0 {
761 return ErrNil
762 }
763 for i := 0; i < l; i++ {
764 o.buf = append(o.buf, p.tagcode...)
765 x := s.Index(i)
766 p.valEnc(o, uint64(x))
767 }
768 return nil
769}
770
771func size_slice_uint32(p *Properties, base structPointer) (n int) {
772 s := structPointer_Word32Slice(base, p.field)
773 l := s.Len()
774 if l == 0 {
775 return 0
776 }
777 for i := 0; i < l; i++ {
778 n += len(p.tagcode)
779 x := s.Index(i)
780 n += p.valSize(uint64(x))
781 }
782 return
783}
784
785// Encode a slice of uint32s ([]uint32) in packed format.
786// Exactly the same as int32, except for no sign extension.
787func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
788 s := structPointer_Word32Slice(base, p.field)
789 l := s.Len()
790 if l == 0 {
791 return ErrNil
792 }
793 // TODO: Reuse a Buffer.
794 buf := NewBuffer(nil)
795 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000796 p.valEnc(buf, uint64(s.Index(i)))
David Symonds5b7775e2010-12-01 10:09:04 +1100797 }
798
799 o.buf = append(o.buf, p.tagcode...)
800 o.EncodeVarint(uint64(len(buf.buf)))
801 o.buf = append(o.buf, buf.buf...)
802 return nil
803}
804
David Symonds0ec36a22014-08-12 13:21:46 +1000805func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
David Symonds0bf1ad52013-10-11 09:07:50 +1100806 s := structPointer_Word32Slice(base, p.field)
807 l := s.Len()
808 if l == 0 {
809 return 0
810 }
811 var bufSize int
812 for i := 0; i < l; i++ {
813 bufSize += p.valSize(uint64(s.Index(i)))
814 }
815
816 n += len(p.tagcode)
817 n += sizeVarint(uint64(bufSize))
818 n += bufSize
819 return
820}
821
Rob Pikeaaa3a622010-03-20 22:32:34 -0700822// Encode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000823func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
824 s := structPointer_Word64Slice(base, p.field)
825 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700826 if l == 0 {
827 return ErrNil
828 }
829 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800830 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000831 p.valEnc(o, s.Index(i))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700832 }
833 return nil
834}
835
David Symonds0bf1ad52013-10-11 09:07:50 +1100836func size_slice_int64(p *Properties, base structPointer) (n int) {
837 s := structPointer_Word64Slice(base, p.field)
838 l := s.Len()
839 if l == 0 {
840 return 0
841 }
842 for i := 0; i < l; i++ {
843 n += len(p.tagcode)
844 n += p.valSize(s.Index(i))
845 }
846 return
847}
848
David Symonds5b7775e2010-12-01 10:09:04 +1100849// Encode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000850func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
851 s := structPointer_Word64Slice(base, p.field)
852 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100853 if l == 0 {
854 return ErrNil
855 }
856 // TODO: Reuse a Buffer.
857 buf := NewBuffer(nil)
858 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000859 p.valEnc(buf, s.Index(i))
David Symonds5b7775e2010-12-01 10:09:04 +1100860 }
861
862 o.buf = append(o.buf, p.tagcode...)
863 o.EncodeVarint(uint64(len(buf.buf)))
864 o.buf = append(o.buf, buf.buf...)
865 return nil
866}
867
David Symonds0bf1ad52013-10-11 09:07:50 +1100868func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
869 s := structPointer_Word64Slice(base, p.field)
870 l := s.Len()
871 if l == 0 {
872 return 0
873 }
874 var bufSize int
875 for i := 0; i < l; i++ {
876 bufSize += p.valSize(s.Index(i))
877 }
878
879 n += len(p.tagcode)
880 n += sizeVarint(uint64(bufSize))
881 n += bufSize
882 return
883}
884
Rob Pikeaaa3a622010-03-20 22:32:34 -0700885// Encode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000886func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
887 ss := *structPointer_BytesSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700888 l := len(ss)
889 if l == 0 {
890 return ErrNil
891 }
892 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800893 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100894 o.EncodeRawBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700895 }
896 return nil
897}
898
David Symonds0bf1ad52013-10-11 09:07:50 +1100899func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
900 ss := *structPointer_BytesSlice(base, p.field)
901 l := len(ss)
902 if l == 0 {
903 return 0
904 }
905 n += l * len(p.tagcode)
906 for i := 0; i < l; i++ {
907 n += sizeRawBytes(ss[i])
908 }
909 return
910}
911
Rob Pikeaaa3a622010-03-20 22:32:34 -0700912// Encode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000913func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
914 ss := *structPointer_StringSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700915 l := len(ss)
916 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800917 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100918 o.EncodeStringBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700919 }
920 return nil
921}
922
David Symonds0bf1ad52013-10-11 09:07:50 +1100923func size_slice_string(p *Properties, base structPointer) (n int) {
924 ss := *structPointer_StringSlice(base, p.field)
925 l := len(ss)
926 n += l * len(p.tagcode)
927 for i := 0; i < l; i++ {
928 n += sizeStringBytes(ss[i])
929 }
930 return
931}
932
Rob Pikeaaa3a622010-03-20 22:32:34 -0700933// Encode a slice of message structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000934func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000935 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000936 s := structPointer_StructPointerSlice(base, p.field)
937 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700938
939 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000940 structp := s.Index(i)
941 if structPointer_IsNil(structp) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700942 return ErrRepeatedHasNil
943 }
944
945 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100946 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000947 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700948 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000949 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700950 return err
951 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800952 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700953 o.EncodeRawBytes(data)
954 continue
955 }
956
David Symonds1d8ba132014-01-13 16:01:15 +1100957 o.buf = append(o.buf, p.tagcode...)
David Symondsba7896c2014-11-20 15:29:05 +1100958 err := o.enc_len_struct(p.sprop, structp, &state)
David Symonds4646c372013-09-09 13:18:58 +1000959 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700960 if err == ErrNil {
961 return ErrRepeatedHasNil
962 }
963 return err
964 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700965 }
David Symonds4646c372013-09-09 13:18:58 +1000966 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700967}
968
David Symonds0bf1ad52013-10-11 09:07:50 +1100969func size_slice_struct_message(p *Properties, base structPointer) (n int) {
970 s := structPointer_StructPointerSlice(base, p.field)
971 l := s.Len()
972 n += l * len(p.tagcode)
973 for i := 0; i < l; i++ {
974 structp := s.Index(i)
975 if structPointer_IsNil(structp) {
976 return // return the size up to this point
977 }
978
979 // Can the object marshal itself?
980 if p.isMarshaler {
981 m := structPointer_Interface(structp, p.stype).(Marshaler)
982 data, _ := m.Marshal()
983 n += len(p.tagcode)
984 n += sizeRawBytes(data)
985 continue
986 }
987
David Symondsba7896c2014-11-20 15:29:05 +1100988 n0 := size_struct(p.sprop, structp)
David Symonds0bf1ad52013-10-11 09:07:50 +1100989 n1 := sizeVarint(uint64(n0)) // size of encoded length
990 n += n0 + n1
991 }
992 return
993}
994
Rob Pikeaaa3a622010-03-20 22:32:34 -0700995// Encode a slice of group structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000996func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000997 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000998 s := structPointer_StructPointerSlice(base, p.field)
999 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -07001000
1001 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +10001002 b := s.Index(i)
1003 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -07001004 return ErrRepeatedHasNil
1005 }
1006
1007 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
1008
David Symondsba7896c2014-11-20 15:29:05 +11001009 err := o.enc_struct(p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001010
David Symonds4646c372013-09-09 13:18:58 +10001011 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -07001012 if err == ErrNil {
1013 return ErrRepeatedHasNil
1014 }
1015 return err
1016 }
1017
1018 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
1019 }
David Symonds4646c372013-09-09 13:18:58 +10001020 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -07001021}
1022
David Symonds0bf1ad52013-10-11 09:07:50 +11001023func size_slice_struct_group(p *Properties, base structPointer) (n int) {
1024 s := structPointer_StructPointerSlice(base, p.field)
1025 l := s.Len()
1026
1027 n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
1028 n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
1029 for i := 0; i < l; i++ {
1030 b := s.Index(i)
1031 if structPointer_IsNil(b) {
1032 return // return size up to this point
1033 }
1034
David Symondsba7896c2014-11-20 15:29:05 +11001035 n += size_struct(p.sprop, b)
David Symonds0bf1ad52013-10-11 09:07:50 +11001036 }
1037 return
1038}
1039
Rob Pikeaaa3a622010-03-20 22:32:34 -07001040// Encode an extension map.
Russ Coxd4ce3f12012-09-12 10:36:26 +10001041func (o *Buffer) enc_map(p *Properties, base structPointer) error {
1042 v := *structPointer_ExtMap(base, p.field)
David Symonds1d72f7a2011-08-19 18:28:52 +10001043 if err := encodeExtensionMap(v); err != nil {
1044 return err
1045 }
David Symondsdf583ae2012-12-06 14:06:53 +11001046 // Fast-path for common cases: zero or one extensions.
1047 if len(v) <= 1 {
1048 for _, e := range v {
1049 o.buf = append(o.buf, e.enc...)
1050 }
1051 return nil
1052 }
1053
1054 // Sort keys to provide a deterministic encoding.
1055 keys := make([]int, 0, len(v))
1056 for k := range v {
1057 keys = append(keys, int(k))
1058 }
1059 sort.Ints(keys)
1060
1061 for _, k := range keys {
1062 o.buf = append(o.buf, v[int32(k)].enc...)
Rob Pikeaaa3a622010-03-20 22:32:34 -07001063 }
1064 return nil
1065}
1066
David Symonds0bf1ad52013-10-11 09:07:50 +11001067func size_map(p *Properties, base structPointer) int {
1068 v := *structPointer_ExtMap(base, p.field)
1069 return sizeExtensionMap(v)
1070}
1071
David Symonds3ea3e052014-12-22 16:15:28 +11001072// Encode a map field.
1073func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
1074 var state errorState // XXX: or do we need to plumb this through?
1075
1076 /*
1077 A map defined as
1078 map<key_type, value_type> map_field = N;
1079 is encoded in the same way as
1080 message MapFieldEntry {
1081 key_type key = 1;
1082 value_type value = 2;
1083 }
1084 repeated MapFieldEntry map_field = N;
1085 */
1086
1087 v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
1088 if v.Len() == 0 {
1089 return nil
1090 }
1091
1092 keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
1093
1094 enc := func() error {
1095 if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
1096 return err
1097 }
1098 if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
1099 return err
1100 }
1101 return nil
1102 }
1103
David Symonds7f079252015-01-09 11:09:00 +11001104 keys := v.MapKeys()
1105 sort.Sort(mapKeys(keys))
1106 for _, key := range keys {
David Symonds3ea3e052014-12-22 16:15:28 +11001107 val := v.MapIndex(key)
1108
1109 keycopy.Set(key)
1110 valcopy.Set(val)
1111
1112 o.buf = append(o.buf, p.tagcode...)
1113 if err := o.enc_len_thing(enc, &state); err != nil {
1114 return err
1115 }
1116 }
1117 return nil
1118}
1119
1120func size_new_map(p *Properties, base structPointer) int {
1121 v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
1122
1123 keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
1124
1125 n := 0
1126 for _, key := range v.MapKeys() {
1127 val := v.MapIndex(key)
1128 keycopy.Set(key)
1129 valcopy.Set(val)
1130
1131 // Tag codes are two bytes per map entry.
1132 n += 2
1133 n += p.mkeyprop.size(p.mkeyprop, keybase)
1134 n += p.mvalprop.size(p.mvalprop, valbase)
1135 }
1136 return n
1137}
1138
1139// mapEncodeScratch returns a new reflect.Value matching the map's value type,
1140// and a structPointer suitable for passing to an encoder or sizer.
1141func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
1142 // Prepare addressable doubly-indirect placeholders for the key and value types.
1143 // This is needed because the element-type encoders expect **T, but the map iteration produces T.
1144
1145 keycopy = reflect.New(mapType.Key()).Elem() // addressable K
1146 keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
1147 keyptr.Set(keycopy.Addr()) //
1148 keybase = toStructPointer(keyptr.Addr()) // **K
1149
1150 // Value types are more varied and require special handling.
1151 switch mapType.Elem().Kind() {
1152 case reflect.Slice:
1153 // []byte
1154 var dummy []byte
1155 valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
1156 valbase = toStructPointer(valcopy.Addr())
1157 case reflect.Ptr:
1158 // message; the generated field type is map[K]*Msg (so V is *Msg),
1159 // so we only need one level of indirection.
1160 valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
1161 valbase = toStructPointer(valcopy.Addr())
1162 default:
1163 // everything else
1164 valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
1165 valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
1166 valptr.Set(valcopy.Addr()) //
1167 valbase = toStructPointer(valptr.Addr()) // **V
1168 }
1169 return
1170}
1171
Rob Pikeaaa3a622010-03-20 22:32:34 -07001172// Encode a struct.
David Symondsba7896c2014-11-20 15:29:05 +11001173func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +10001174 var state errorState
David Symondsd15e81b2011-10-03 14:31:12 -07001175 // Encode fields in tag order so that decoders may use optimizations
1176 // that depend on the ordering.
David Symonds380d2d02014-11-24 10:50:43 +11001177 // https://developers.google.com/protocol-buffers/docs/encoding#order
David Symondsd15e81b2011-10-03 14:31:12 -07001178 for _, i := range prop.order {
1179 p := prop.Prop[i]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001180 if p.enc != nil {
1181 err := p.enc(o, p, base)
David Symonds4a2eeb52013-09-25 11:54:08 +10001182 if err != nil {
1183 if err == ErrNil {
1184 if p.Required && state.err == nil {
David Symondse583a5f2013-09-27 10:02:37 +10001185 state.err = &RequiredNotSetError{p.Name}
David Symonds4a2eeb52013-09-25 11:54:08 +10001186 }
1187 } else if !state.shouldContinue(err, p) {
Rob Pikeaaa3a622010-03-20 22:32:34 -07001188 return err
1189 }
Rob Pikeaaa3a622010-03-20 22:32:34 -07001190 }
1191 }
1192 }
Rob Pikeaaa3a622010-03-20 22:32:34 -07001193
David Symonds10c93ba2012-08-04 16:38:08 +10001194 // Add unrecognized fields at the end.
Russ Coxd4ce3f12012-09-12 10:36:26 +10001195 if prop.unrecField.IsValid() {
1196 v := *structPointer_Bytes(base, prop.unrecField)
1197 if len(v) > 0 {
1198 o.buf = append(o.buf, v...)
1199 }
David Symonds10c93ba2012-08-04 16:38:08 +10001200 }
1201
David Symonds4646c372013-09-09 13:18:58 +10001202 return state.err
1203}
1204
David Symondsba7896c2014-11-20 15:29:05 +11001205func size_struct(prop *StructProperties, base structPointer) (n int) {
David Symonds0bf1ad52013-10-11 09:07:50 +11001206 for _, i := range prop.order {
1207 p := prop.Prop[i]
1208 if p.size != nil {
1209 n += p.size(p, base)
1210 }
1211 }
1212
1213 // Add unrecognized fields at the end.
1214 if prop.unrecField.IsValid() {
1215 v := *structPointer_Bytes(base, prop.unrecField)
1216 n += len(v)
1217 }
1218
1219 return
1220}
1221
David Symonds1d8ba132014-01-13 16:01:15 +11001222var zeroes [20]byte // longer than any conceivable sizeVarint
1223
1224// Encode a struct, preceded by its encoded length (as a varint).
David Symondsba7896c2014-11-20 15:29:05 +11001225func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
David Symonds3ea3e052014-12-22 16:15:28 +11001226 return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
1227}
1228
1229// Encode something, preceded by its encoded length (as a varint).
1230func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
David Symonds1d8ba132014-01-13 16:01:15 +11001231 iLen := len(o.buf)
1232 o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
1233 iMsg := len(o.buf)
David Symonds3ea3e052014-12-22 16:15:28 +11001234 err := enc()
David Symonds1d8ba132014-01-13 16:01:15 +11001235 if err != nil && !state.shouldContinue(err, nil) {
1236 return err
1237 }
1238 lMsg := len(o.buf) - iMsg
1239 lLen := sizeVarint(uint64(lMsg))
1240 switch x := lLen - (iMsg - iLen); {
1241 case x > 0: // actual length is x bytes larger than the space we reserved
1242 // Move msg x bytes right.
1243 o.buf = append(o.buf, zeroes[:x]...)
1244 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
1245 case x < 0: // actual length is x bytes smaller than the space we reserved
1246 // Move msg x bytes left.
1247 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
1248 o.buf = o.buf[:len(o.buf)+x] // x is negative
1249 }
1250 // Encode the length in the reserved space.
1251 o.buf = o.buf[:iLen]
1252 o.EncodeVarint(uint64(lMsg))
1253 o.buf = o.buf[:len(o.buf)+lMsg]
1254 return state.err
1255}
1256
David Symonds4646c372013-09-09 13:18:58 +10001257// errorState maintains the first error that occurs and updates that error
1258// with additional context.
1259type errorState struct {
1260 err error
1261}
1262
1263// shouldContinue reports whether encoding should continue upon encountering the
David Symondse583a5f2013-09-27 10:02:37 +10001264// given error. If the error is RequiredNotSetError, shouldContinue returns true
David Symonds4646c372013-09-09 13:18:58 +10001265// and, if this is the first appearance of that error, remembers it for future
1266// reporting.
1267//
1268// If prop is not nil, it may update any error with additional context about the
1269// field with the error.
1270func (s *errorState) shouldContinue(err error, prop *Properties) bool {
1271 // Ignore unset required fields.
David Symondse583a5f2013-09-27 10:02:37 +10001272 reqNotSet, ok := err.(*RequiredNotSetError)
David Symonds4646c372013-09-09 13:18:58 +10001273 if !ok {
1274 return false
1275 }
1276 if s.err == nil {
1277 if prop != nil {
David Symondse583a5f2013-09-27 10:02:37 +10001278 err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
David Symonds4646c372013-09-09 13:18:58 +10001279 }
1280 s.err = err
1281 }
1282 return true
Rob Pikeaaa3a622010-03-20 22:32:34 -07001283}