blob: cbe4242e0071ebddfb60f6ef3be66376c7cdb117 [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 Symonds0bf1ad52013-10-11 09:07:50 +1100301func size_bool(p *Properties, base structPointer) int {
302 v := *structPointer_Bool(base, p.field)
303 if v == nil {
304 return 0
305 }
306 return len(p.tagcode) + 1 // each bool takes exactly one byte
307}
308
Rob Pikeaaa3a622010-03-20 22:32:34 -0700309// Encode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000310func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
311 v := structPointer_Word32(base, p.field)
312 if word32_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700313 return ErrNil
314 }
David Symondsf054e842014-07-22 14:06:27 +1000315 x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
Rob Pike99fa2b62010-12-02 10:39:42 -0800316 o.buf = append(o.buf, p.tagcode...)
David Symondsc31645c2013-06-22 17:57:36 +1000317 p.valEnc(o, uint64(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700318 return nil
319}
320
David Symonds0bf1ad52013-10-11 09:07:50 +1100321func size_int32(p *Properties, base structPointer) (n int) {
322 v := structPointer_Word32(base, p.field)
323 if word32_IsNil(v) {
324 return 0
325 }
David Symondsf054e842014-07-22 14:06:27 +1000326 x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
327 n += len(p.tagcode)
328 n += p.valSize(uint64(x))
329 return
330}
331
332// Encode a uint32.
333// Exactly the same as int32, except for no sign extension.
334func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
335 v := structPointer_Word32(base, p.field)
336 if word32_IsNil(v) {
337 return ErrNil
338 }
339 x := word32_Get(v)
340 o.buf = append(o.buf, p.tagcode...)
341 p.valEnc(o, uint64(x))
342 return nil
343}
344
345func size_uint32(p *Properties, base structPointer) (n int) {
346 v := structPointer_Word32(base, p.field)
347 if word32_IsNil(v) {
348 return 0
349 }
David Symonds0bf1ad52013-10-11 09:07:50 +1100350 x := word32_Get(v)
351 n += len(p.tagcode)
352 n += p.valSize(uint64(x))
353 return
354}
355
Rob Pikeaaa3a622010-03-20 22:32:34 -0700356// Encode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000357func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
358 v := structPointer_Word64(base, p.field)
359 if word64_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700360 return ErrNil
361 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000362 x := word64_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800363 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000364 p.valEnc(o, x)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700365 return nil
366}
367
David Symonds0bf1ad52013-10-11 09:07:50 +1100368func size_int64(p *Properties, base structPointer) (n int) {
369 v := structPointer_Word64(base, p.field)
370 if word64_IsNil(v) {
371 return 0
372 }
373 x := word64_Get(v)
374 n += len(p.tagcode)
375 n += p.valSize(x)
376 return
377}
378
Rob Pikeaaa3a622010-03-20 22:32:34 -0700379// Encode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000380func (o *Buffer) enc_string(p *Properties, base structPointer) error {
381 v := *structPointer_String(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700382 if v == nil {
383 return ErrNil
384 }
385 x := *v
Rob Pike99fa2b62010-12-02 10:39:42 -0800386 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700387 o.EncodeStringBytes(x)
388 return nil
389}
390
David Symonds0bf1ad52013-10-11 09:07:50 +1100391func size_string(p *Properties, base structPointer) (n int) {
392 v := *structPointer_String(base, p.field)
393 if v == nil {
394 return 0
395 }
396 x := *v
397 n += len(p.tagcode)
398 n += sizeStringBytes(x)
399 return
400}
401
Rob Pike97e934d2011-04-11 12:52:49 -0700402// All protocol buffer fields are nillable, but be careful.
403func isNil(v reflect.Value) bool {
404 switch v.Kind() {
David Symonds007ed9d2012-07-24 10:59:36 +1000405 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
Rob Pike97e934d2011-04-11 12:52:49 -0700406 return v.IsNil()
407 }
408 return false
409}
410
Rob Pikeaaa3a622010-03-20 22:32:34 -0700411// Encode a message struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000412func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000413 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000414 structp := structPointer_GetStructPointer(base, p.field)
415 if structPointer_IsNil(structp) {
David Symondsa80b2822012-03-14 14:31:25 +1100416 return ErrNil
417 }
418
Rob Pikeaaa3a622010-03-20 22:32:34 -0700419 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100420 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000421 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700422 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000423 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700424 return err
425 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800426 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700427 o.EncodeRawBytes(data)
428 return nil
429 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700430
Rob Pike99fa2b62010-12-02 10:39:42 -0800431 o.buf = append(o.buf, p.tagcode...)
David Symondsba7896c2014-11-20 15:29:05 +1100432 return o.enc_len_struct(p.sprop, structp, &state)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700433}
434
David Symonds0bf1ad52013-10-11 09:07:50 +1100435func size_struct_message(p *Properties, base structPointer) int {
436 structp := structPointer_GetStructPointer(base, p.field)
437 if structPointer_IsNil(structp) {
438 return 0
439 }
440
441 // Can the object marshal itself?
442 if p.isMarshaler {
443 m := structPointer_Interface(structp, p.stype).(Marshaler)
444 data, _ := m.Marshal()
445 n0 := len(p.tagcode)
446 n1 := sizeRawBytes(data)
447 return n0 + n1
448 }
449
450 n0 := len(p.tagcode)
David Symondsba7896c2014-11-20 15:29:05 +1100451 n1 := size_struct(p.sprop, structp)
David Symonds0bf1ad52013-10-11 09:07:50 +1100452 n2 := sizeVarint(uint64(n1)) // size of encoded length
453 return n0 + n1 + n2
454}
455
Rob Pikeaaa3a622010-03-20 22:32:34 -0700456// Encode a group struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000457func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000458 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000459 b := structPointer_GetStructPointer(base, p.field)
460 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700461 return ErrNil
462 }
463
464 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symondsba7896c2014-11-20 15:29:05 +1100465 err := o.enc_struct(p.sprop, b)
David Symonds4646c372013-09-09 13:18:58 +1000466 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700467 return err
468 }
469 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
David Symonds4646c372013-09-09 13:18:58 +1000470 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700471}
472
David Symonds0bf1ad52013-10-11 09:07:50 +1100473func size_struct_group(p *Properties, base structPointer) (n int) {
474 b := structPointer_GetStructPointer(base, p.field)
475 if structPointer_IsNil(b) {
476 return 0
477 }
478
479 n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symondsba7896c2014-11-20 15:29:05 +1100480 n += size_struct(p.sprop, b)
David Symonds0bf1ad52013-10-11 09:07:50 +1100481 n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
482 return
483}
484
Rob Pikeaaa3a622010-03-20 22:32:34 -0700485// Encode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000486func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
487 s := *structPointer_BoolSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700488 l := len(s)
489 if l == 0 {
490 return ErrNil
491 }
492 for _, x := range s {
Rob Pike99fa2b62010-12-02 10:39:42 -0800493 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000494 v := uint64(0)
495 if x {
496 v = 1
Rob Pikeaaa3a622010-03-20 22:32:34 -0700497 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000498 p.valEnc(o, v)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700499 }
500 return nil
501}
502
David Symonds0bf1ad52013-10-11 09:07:50 +1100503func size_slice_bool(p *Properties, base structPointer) int {
504 s := *structPointer_BoolSlice(base, p.field)
505 l := len(s)
506 if l == 0 {
507 return 0
508 }
509 return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
510}
511
David Symonds5b7775e2010-12-01 10:09:04 +1100512// Encode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000513func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
514 s := *structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100515 l := len(s)
516 if l == 0 {
517 return ErrNil
518 }
519 o.buf = append(o.buf, p.tagcode...)
520 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
521 for _, x := range s {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000522 v := uint64(0)
523 if x {
524 v = 1
David Symonds5b7775e2010-12-01 10:09:04 +1100525 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000526 p.valEnc(o, v)
David Symonds5b7775e2010-12-01 10:09:04 +1100527 }
528 return nil
529}
530
David Symonds0bf1ad52013-10-11 09:07:50 +1100531func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
532 s := *structPointer_BoolSlice(base, p.field)
533 l := len(s)
534 if l == 0 {
535 return 0
536 }
537 n += len(p.tagcode)
538 n += sizeVarint(uint64(l))
539 n += l // each bool takes exactly one byte
540 return
541}
542
Rob Pikeaaa3a622010-03-20 22:32:34 -0700543// Encode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000544func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
545 s := *structPointer_Bytes(base, p.field)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800546 if s == nil {
547 return ErrNil
548 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800549 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700550 o.EncodeRawBytes(s)
551 return nil
552}
553
David Symonds0bf1ad52013-10-11 09:07:50 +1100554func size_slice_byte(p *Properties, base structPointer) (n int) {
555 s := *structPointer_Bytes(base, p.field)
556 if s == nil {
557 return 0
558 }
559 n += len(p.tagcode)
560 n += sizeRawBytes(s)
561 return
562}
563
Rob Pikeaaa3a622010-03-20 22:32:34 -0700564// Encode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000565func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
566 s := structPointer_Word32Slice(base, p.field)
567 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700568 if l == 0 {
569 return ErrNil
570 }
571 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800572 o.buf = append(o.buf, p.tagcode...)
David Symonds0ec36a22014-08-12 13:21:46 +1000573 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
Rob Pikeaaa3a622010-03-20 22:32:34 -0700574 p.valEnc(o, uint64(x))
575 }
576 return nil
577}
578
David Symonds0bf1ad52013-10-11 09:07:50 +1100579func size_slice_int32(p *Properties, base structPointer) (n int) {
580 s := structPointer_Word32Slice(base, p.field)
581 l := s.Len()
582 if l == 0 {
583 return 0
584 }
585 for i := 0; i < l; i++ {
586 n += len(p.tagcode)
David Symonds0ec36a22014-08-12 13:21:46 +1000587 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
David Symonds0bf1ad52013-10-11 09:07:50 +1100588 n += p.valSize(uint64(x))
589 }
590 return
591}
592
David Symonds5b7775e2010-12-01 10:09:04 +1100593// Encode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000594func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
595 s := structPointer_Word32Slice(base, p.field)
596 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100597 if l == 0 {
598 return ErrNil
599 }
600 // TODO: Reuse a Buffer.
601 buf := NewBuffer(nil)
602 for i := 0; i < l; i++ {
David Symonds0ec36a22014-08-12 13:21:46 +1000603 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
604 p.valEnc(buf, uint64(x))
605 }
606
607 o.buf = append(o.buf, p.tagcode...)
608 o.EncodeVarint(uint64(len(buf.buf)))
609 o.buf = append(o.buf, buf.buf...)
610 return nil
611}
612
613func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
614 s := structPointer_Word32Slice(base, p.field)
615 l := s.Len()
616 if l == 0 {
617 return 0
618 }
619 var bufSize int
620 for i := 0; i < l; i++ {
621 x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
622 bufSize += p.valSize(uint64(x))
623 }
624
625 n += len(p.tagcode)
626 n += sizeVarint(uint64(bufSize))
627 n += bufSize
628 return
629}
630
631// Encode a slice of uint32s ([]uint32).
632// Exactly the same as int32, except for no sign extension.
633func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
634 s := structPointer_Word32Slice(base, p.field)
635 l := s.Len()
636 if l == 0 {
637 return ErrNil
638 }
639 for i := 0; i < l; i++ {
640 o.buf = append(o.buf, p.tagcode...)
641 x := s.Index(i)
642 p.valEnc(o, uint64(x))
643 }
644 return nil
645}
646
647func size_slice_uint32(p *Properties, base structPointer) (n int) {
648 s := structPointer_Word32Slice(base, p.field)
649 l := s.Len()
650 if l == 0 {
651 return 0
652 }
653 for i := 0; i < l; i++ {
654 n += len(p.tagcode)
655 x := s.Index(i)
656 n += p.valSize(uint64(x))
657 }
658 return
659}
660
661// Encode a slice of uint32s ([]uint32) in packed format.
662// Exactly the same as int32, except for no sign extension.
663func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
664 s := structPointer_Word32Slice(base, p.field)
665 l := s.Len()
666 if l == 0 {
667 return ErrNil
668 }
669 // TODO: Reuse a Buffer.
670 buf := NewBuffer(nil)
671 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000672 p.valEnc(buf, uint64(s.Index(i)))
David Symonds5b7775e2010-12-01 10:09:04 +1100673 }
674
675 o.buf = append(o.buf, p.tagcode...)
676 o.EncodeVarint(uint64(len(buf.buf)))
677 o.buf = append(o.buf, buf.buf...)
678 return nil
679}
680
David Symonds0ec36a22014-08-12 13:21:46 +1000681func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
David Symonds0bf1ad52013-10-11 09:07:50 +1100682 s := structPointer_Word32Slice(base, p.field)
683 l := s.Len()
684 if l == 0 {
685 return 0
686 }
687 var bufSize int
688 for i := 0; i < l; i++ {
689 bufSize += p.valSize(uint64(s.Index(i)))
690 }
691
692 n += len(p.tagcode)
693 n += sizeVarint(uint64(bufSize))
694 n += bufSize
695 return
696}
697
Rob Pikeaaa3a622010-03-20 22:32:34 -0700698// Encode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000699func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
700 s := structPointer_Word64Slice(base, p.field)
701 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700702 if l == 0 {
703 return ErrNil
704 }
705 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800706 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000707 p.valEnc(o, s.Index(i))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700708 }
709 return nil
710}
711
David Symonds0bf1ad52013-10-11 09:07:50 +1100712func size_slice_int64(p *Properties, base structPointer) (n int) {
713 s := structPointer_Word64Slice(base, p.field)
714 l := s.Len()
715 if l == 0 {
716 return 0
717 }
718 for i := 0; i < l; i++ {
719 n += len(p.tagcode)
720 n += p.valSize(s.Index(i))
721 }
722 return
723}
724
David Symonds5b7775e2010-12-01 10:09:04 +1100725// Encode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000726func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
727 s := structPointer_Word64Slice(base, p.field)
728 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100729 if l == 0 {
730 return ErrNil
731 }
732 // TODO: Reuse a Buffer.
733 buf := NewBuffer(nil)
734 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000735 p.valEnc(buf, s.Index(i))
David Symonds5b7775e2010-12-01 10:09:04 +1100736 }
737
738 o.buf = append(o.buf, p.tagcode...)
739 o.EncodeVarint(uint64(len(buf.buf)))
740 o.buf = append(o.buf, buf.buf...)
741 return nil
742}
743
David Symonds0bf1ad52013-10-11 09:07:50 +1100744func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
745 s := structPointer_Word64Slice(base, p.field)
746 l := s.Len()
747 if l == 0 {
748 return 0
749 }
750 var bufSize int
751 for i := 0; i < l; i++ {
752 bufSize += p.valSize(s.Index(i))
753 }
754
755 n += len(p.tagcode)
756 n += sizeVarint(uint64(bufSize))
757 n += bufSize
758 return
759}
760
Rob Pikeaaa3a622010-03-20 22:32:34 -0700761// Encode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000762func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
763 ss := *structPointer_BytesSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700764 l := len(ss)
765 if l == 0 {
766 return ErrNil
767 }
768 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800769 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100770 o.EncodeRawBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700771 }
772 return nil
773}
774
David Symonds0bf1ad52013-10-11 09:07:50 +1100775func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
776 ss := *structPointer_BytesSlice(base, p.field)
777 l := len(ss)
778 if l == 0 {
779 return 0
780 }
781 n += l * len(p.tagcode)
782 for i := 0; i < l; i++ {
783 n += sizeRawBytes(ss[i])
784 }
785 return
786}
787
Rob Pikeaaa3a622010-03-20 22:32:34 -0700788// Encode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000789func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
790 ss := *structPointer_StringSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700791 l := len(ss)
792 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800793 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100794 o.EncodeStringBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700795 }
796 return nil
797}
798
David Symonds0bf1ad52013-10-11 09:07:50 +1100799func size_slice_string(p *Properties, base structPointer) (n int) {
800 ss := *structPointer_StringSlice(base, p.field)
801 l := len(ss)
802 n += l * len(p.tagcode)
803 for i := 0; i < l; i++ {
804 n += sizeStringBytes(ss[i])
805 }
806 return
807}
808
Rob Pikeaaa3a622010-03-20 22:32:34 -0700809// Encode a slice of message structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000810func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000811 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000812 s := structPointer_StructPointerSlice(base, p.field)
813 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700814
815 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000816 structp := s.Index(i)
817 if structPointer_IsNil(structp) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700818 return ErrRepeatedHasNil
819 }
820
821 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100822 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000823 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700824 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000825 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700826 return err
827 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800828 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700829 o.EncodeRawBytes(data)
830 continue
831 }
832
David Symonds1d8ba132014-01-13 16:01:15 +1100833 o.buf = append(o.buf, p.tagcode...)
David Symondsba7896c2014-11-20 15:29:05 +1100834 err := o.enc_len_struct(p.sprop, structp, &state)
David Symonds4646c372013-09-09 13:18:58 +1000835 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700836 if err == ErrNil {
837 return ErrRepeatedHasNil
838 }
839 return err
840 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700841 }
David Symonds4646c372013-09-09 13:18:58 +1000842 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700843}
844
David Symonds0bf1ad52013-10-11 09:07:50 +1100845func size_slice_struct_message(p *Properties, base structPointer) (n int) {
846 s := structPointer_StructPointerSlice(base, p.field)
847 l := s.Len()
848 n += l * len(p.tagcode)
849 for i := 0; i < l; i++ {
850 structp := s.Index(i)
851 if structPointer_IsNil(structp) {
852 return // return the size up to this point
853 }
854
855 // Can the object marshal itself?
856 if p.isMarshaler {
857 m := structPointer_Interface(structp, p.stype).(Marshaler)
858 data, _ := m.Marshal()
859 n += len(p.tagcode)
860 n += sizeRawBytes(data)
861 continue
862 }
863
David Symondsba7896c2014-11-20 15:29:05 +1100864 n0 := size_struct(p.sprop, structp)
David Symonds0bf1ad52013-10-11 09:07:50 +1100865 n1 := sizeVarint(uint64(n0)) // size of encoded length
866 n += n0 + n1
867 }
868 return
869}
870
Rob Pikeaaa3a622010-03-20 22:32:34 -0700871// Encode a slice of group structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000872func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000873 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000874 s := structPointer_StructPointerSlice(base, p.field)
875 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700876
877 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000878 b := s.Index(i)
879 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700880 return ErrRepeatedHasNil
881 }
882
883 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
884
David Symondsba7896c2014-11-20 15:29:05 +1100885 err := o.enc_struct(p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700886
David Symonds4646c372013-09-09 13:18:58 +1000887 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700888 if err == ErrNil {
889 return ErrRepeatedHasNil
890 }
891 return err
892 }
893
894 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
895 }
David Symonds4646c372013-09-09 13:18:58 +1000896 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700897}
898
David Symonds0bf1ad52013-10-11 09:07:50 +1100899func size_slice_struct_group(p *Properties, base structPointer) (n int) {
900 s := structPointer_StructPointerSlice(base, p.field)
901 l := s.Len()
902
903 n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
904 n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
905 for i := 0; i < l; i++ {
906 b := s.Index(i)
907 if structPointer_IsNil(b) {
908 return // return size up to this point
909 }
910
David Symondsba7896c2014-11-20 15:29:05 +1100911 n += size_struct(p.sprop, b)
David Symonds0bf1ad52013-10-11 09:07:50 +1100912 }
913 return
914}
915
Rob Pikeaaa3a622010-03-20 22:32:34 -0700916// Encode an extension map.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000917func (o *Buffer) enc_map(p *Properties, base structPointer) error {
918 v := *structPointer_ExtMap(base, p.field)
David Symonds1d72f7a2011-08-19 18:28:52 +1000919 if err := encodeExtensionMap(v); err != nil {
920 return err
921 }
David Symondsdf583ae2012-12-06 14:06:53 +1100922 // Fast-path for common cases: zero or one extensions.
923 if len(v) <= 1 {
924 for _, e := range v {
925 o.buf = append(o.buf, e.enc...)
926 }
927 return nil
928 }
929
930 // Sort keys to provide a deterministic encoding.
931 keys := make([]int, 0, len(v))
932 for k := range v {
933 keys = append(keys, int(k))
934 }
935 sort.Ints(keys)
936
937 for _, k := range keys {
938 o.buf = append(o.buf, v[int32(k)].enc...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700939 }
940 return nil
941}
942
David Symonds0bf1ad52013-10-11 09:07:50 +1100943func size_map(p *Properties, base structPointer) int {
944 v := *structPointer_ExtMap(base, p.field)
945 return sizeExtensionMap(v)
946}
947
Rob Pikeaaa3a622010-03-20 22:32:34 -0700948// Encode a struct.
David Symondsba7896c2014-11-20 15:29:05 +1100949func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000950 var state errorState
David Symondsd15e81b2011-10-03 14:31:12 -0700951 // Encode fields in tag order so that decoders may use optimizations
952 // that depend on the ordering.
David Symonds380d2d02014-11-24 10:50:43 +1100953 // https://developers.google.com/protocol-buffers/docs/encoding#order
David Symondsd15e81b2011-10-03 14:31:12 -0700954 for _, i := range prop.order {
955 p := prop.Prop[i]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700956 if p.enc != nil {
957 err := p.enc(o, p, base)
David Symonds4a2eeb52013-09-25 11:54:08 +1000958 if err != nil {
959 if err == ErrNil {
960 if p.Required && state.err == nil {
David Symondse583a5f2013-09-27 10:02:37 +1000961 state.err = &RequiredNotSetError{p.Name}
David Symonds4a2eeb52013-09-25 11:54:08 +1000962 }
963 } else if !state.shouldContinue(err, p) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700964 return err
965 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700966 }
967 }
968 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700969
David Symonds10c93ba2012-08-04 16:38:08 +1000970 // Add unrecognized fields at the end.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000971 if prop.unrecField.IsValid() {
972 v := *structPointer_Bytes(base, prop.unrecField)
973 if len(v) > 0 {
974 o.buf = append(o.buf, v...)
975 }
David Symonds10c93ba2012-08-04 16:38:08 +1000976 }
977
David Symonds4646c372013-09-09 13:18:58 +1000978 return state.err
979}
980
David Symondsba7896c2014-11-20 15:29:05 +1100981func size_struct(prop *StructProperties, base structPointer) (n int) {
David Symonds0bf1ad52013-10-11 09:07:50 +1100982 for _, i := range prop.order {
983 p := prop.Prop[i]
984 if p.size != nil {
985 n += p.size(p, base)
986 }
987 }
988
989 // Add unrecognized fields at the end.
990 if prop.unrecField.IsValid() {
991 v := *structPointer_Bytes(base, prop.unrecField)
992 n += len(v)
993 }
994
995 return
996}
997
David Symonds1d8ba132014-01-13 16:01:15 +1100998var zeroes [20]byte // longer than any conceivable sizeVarint
999
1000// Encode a struct, preceded by its encoded length (as a varint).
David Symondsba7896c2014-11-20 15:29:05 +11001001func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
David Symonds1d8ba132014-01-13 16:01:15 +11001002 iLen := len(o.buf)
1003 o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
1004 iMsg := len(o.buf)
David Symondsba7896c2014-11-20 15:29:05 +11001005 err := o.enc_struct(prop, base)
David Symonds1d8ba132014-01-13 16:01:15 +11001006 if err != nil && !state.shouldContinue(err, nil) {
1007 return err
1008 }
1009 lMsg := len(o.buf) - iMsg
1010 lLen := sizeVarint(uint64(lMsg))
1011 switch x := lLen - (iMsg - iLen); {
1012 case x > 0: // actual length is x bytes larger than the space we reserved
1013 // Move msg x bytes right.
1014 o.buf = append(o.buf, zeroes[:x]...)
1015 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
1016 case x < 0: // actual length is x bytes smaller than the space we reserved
1017 // Move msg x bytes left.
1018 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
1019 o.buf = o.buf[:len(o.buf)+x] // x is negative
1020 }
1021 // Encode the length in the reserved space.
1022 o.buf = o.buf[:iLen]
1023 o.EncodeVarint(uint64(lMsg))
1024 o.buf = o.buf[:len(o.buf)+lMsg]
1025 return state.err
1026}
1027
David Symonds4646c372013-09-09 13:18:58 +10001028// errorState maintains the first error that occurs and updates that error
1029// with additional context.
1030type errorState struct {
1031 err error
1032}
1033
1034// shouldContinue reports whether encoding should continue upon encountering the
David Symondse583a5f2013-09-27 10:02:37 +10001035// given error. If the error is RequiredNotSetError, shouldContinue returns true
David Symonds4646c372013-09-09 13:18:58 +10001036// and, if this is the first appearance of that error, remembers it for future
1037// reporting.
1038//
1039// If prop is not nil, it may update any error with additional context about the
1040// field with the error.
1041func (s *errorState) shouldContinue(err error, prop *Properties) bool {
1042 // Ignore unset required fields.
David Symondse583a5f2013-09-27 10:02:37 +10001043 reqNotSet, ok := err.(*RequiredNotSetError)
David Symonds4646c372013-09-09 13:18:58 +10001044 if !ok {
1045 return false
1046 }
1047 if s.err == nil {
1048 if prop != nil {
David Symondse583a5f2013-09-27 10:02:37 +10001049 err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
David Symonds4646c372013-09-09 13:18:58 +10001050 }
1051 s.err = err
1052 }
1053 return true
Rob Pikeaaa3a622010-03-20 22:32:34 -07001054}