blob: 29f092e8a903a566fa1d23625b19a100d05762d8 [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.
Rob Pikeaaa3a622010-03-20 22:32:34 -07004// http://code.google.com/p/goprotobuf/
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// * 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 }
224 return p.buf, err
225}
226
David Symonds9f60f432012-06-14 09:45:25 +1000227// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700228// and encodes it into the wire format, writing the result to the
229// Buffer.
David Symonds9f60f432012-06-14 09:45:25 +1000230func (p *Buffer) Marshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700231 // Can the object marshal itself?
232 if m, ok := pb.(Marshaler); ok {
233 data, err := m.Marshal()
234 if err != nil {
235 return err
236 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800237 p.buf = append(p.buf, data...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700238 return nil
239 }
240
Russ Coxd4ce3f12012-09-12 10:36:26 +1000241 t, base, err := getbase(pb)
242 if structPointer_IsNil(base) {
David Symondsd4661c52012-08-30 15:17:53 +1000243 return ErrNil
244 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700245 if err == nil {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000246 err = p.enc_struct(t.Elem(), GetProperties(t.Elem()), base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700247 }
248
David Symonds9f60f432012-06-14 09:45:25 +1000249 if collectStats {
250 stats.Encode++
251 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700252
253 return err
254}
255
David Symonds0bf1ad52013-10-11 09:07:50 +1100256// Size returns the encoded size of a protocol buffer.
257func Size(pb Message) (n int) {
258 // Can the object marshal itself? If so, Size is slow.
259 // TODO: add Size to Marshaler, or add a Sizer interface.
260 if m, ok := pb.(Marshaler); ok {
261 b, _ := m.Marshal()
262 return len(b)
263 }
264
265 t, base, err := getbase(pb)
266 if structPointer_IsNil(base) {
267 return 0
268 }
269 if err == nil {
270 n = size_struct(t.Elem(), GetProperties(t.Elem()), base)
271 }
272
273 if collectStats {
274 stats.Size++
275 }
276
277 return
278}
279
Rob Pikeaaa3a622010-03-20 22:32:34 -0700280// Individual type encoders.
281
282// Encode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000283func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
284 v := *structPointer_Bool(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700285 if v == nil {
286 return ErrNil
287 }
Rob Pike0f42a272011-10-20 16:03:11 -0700288 x := 0
289 if *v {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700290 x = 1
291 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800292 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700293 p.valEnc(o, uint64(x))
294 return nil
295}
296
David Symonds0bf1ad52013-10-11 09:07:50 +1100297func size_bool(p *Properties, base structPointer) int {
298 v := *structPointer_Bool(base, p.field)
299 if v == nil {
300 return 0
301 }
302 return len(p.tagcode) + 1 // each bool takes exactly one byte
303}
304
Rob Pikeaaa3a622010-03-20 22:32:34 -0700305// Encode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000306func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
307 v := structPointer_Word32(base, p.field)
308 if word32_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700309 return ErrNil
310 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000311 x := word32_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800312 o.buf = append(o.buf, p.tagcode...)
David Symondsc31645c2013-06-22 17:57:36 +1000313 p.valEnc(o, uint64(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700314 return nil
315}
316
David Symonds0bf1ad52013-10-11 09:07:50 +1100317func size_int32(p *Properties, base structPointer) (n int) {
318 v := structPointer_Word32(base, p.field)
319 if word32_IsNil(v) {
320 return 0
321 }
322 x := word32_Get(v)
323 n += len(p.tagcode)
324 n += p.valSize(uint64(x))
325 return
326}
327
Rob Pikeaaa3a622010-03-20 22:32:34 -0700328// Encode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000329func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
330 v := structPointer_Word64(base, p.field)
331 if word64_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700332 return ErrNil
333 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000334 x := word64_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800335 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000336 p.valEnc(o, x)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700337 return nil
338}
339
David Symonds0bf1ad52013-10-11 09:07:50 +1100340func size_int64(p *Properties, base structPointer) (n int) {
341 v := structPointer_Word64(base, p.field)
342 if word64_IsNil(v) {
343 return 0
344 }
345 x := word64_Get(v)
346 n += len(p.tagcode)
347 n += p.valSize(x)
348 return
349}
350
Rob Pikeaaa3a622010-03-20 22:32:34 -0700351// Encode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000352func (o *Buffer) enc_string(p *Properties, base structPointer) error {
353 v := *structPointer_String(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700354 if v == nil {
355 return ErrNil
356 }
357 x := *v
Rob Pike99fa2b62010-12-02 10:39:42 -0800358 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700359 o.EncodeStringBytes(x)
360 return nil
361}
362
David Symonds0bf1ad52013-10-11 09:07:50 +1100363func size_string(p *Properties, base structPointer) (n int) {
364 v := *structPointer_String(base, p.field)
365 if v == nil {
366 return 0
367 }
368 x := *v
369 n += len(p.tagcode)
370 n += sizeStringBytes(x)
371 return
372}
373
Rob Pike97e934d2011-04-11 12:52:49 -0700374// All protocol buffer fields are nillable, but be careful.
375func isNil(v reflect.Value) bool {
376 switch v.Kind() {
David Symonds007ed9d2012-07-24 10:59:36 +1000377 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
Rob Pike97e934d2011-04-11 12:52:49 -0700378 return v.IsNil()
379 }
380 return false
381}
382
Rob Pikeaaa3a622010-03-20 22:32:34 -0700383// Encode a message struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000384func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000385 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000386 structp := structPointer_GetStructPointer(base, p.field)
387 if structPointer_IsNil(structp) {
David Symondsa80b2822012-03-14 14:31:25 +1100388 return ErrNil
389 }
390
Rob Pikeaaa3a622010-03-20 22:32:34 -0700391 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100392 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000393 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700394 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000395 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700396 return err
397 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800398 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700399 o.EncodeRawBytes(data)
400 return nil
401 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700402
Rob Pike99fa2b62010-12-02 10:39:42 -0800403 o.buf = append(o.buf, p.tagcode...)
David Symonds1d8ba132014-01-13 16:01:15 +1100404 return o.enc_len_struct(p.stype, p.sprop, structp, &state)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700405}
406
David Symonds0bf1ad52013-10-11 09:07:50 +1100407func size_struct_message(p *Properties, base structPointer) int {
408 structp := structPointer_GetStructPointer(base, p.field)
409 if structPointer_IsNil(structp) {
410 return 0
411 }
412
413 // Can the object marshal itself?
414 if p.isMarshaler {
415 m := structPointer_Interface(structp, p.stype).(Marshaler)
416 data, _ := m.Marshal()
417 n0 := len(p.tagcode)
418 n1 := sizeRawBytes(data)
419 return n0 + n1
420 }
421
422 n0 := len(p.tagcode)
423 n1 := size_struct(p.stype, p.sprop, structp)
424 n2 := sizeVarint(uint64(n1)) // size of encoded length
425 return n0 + n1 + n2
426}
427
Rob Pikeaaa3a622010-03-20 22:32:34 -0700428// Encode a group struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000429func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000430 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000431 b := structPointer_GetStructPointer(base, p.field)
432 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700433 return ErrNil
434 }
435
436 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symonds6a6f82c2012-08-22 09:18:54 +1000437 err := o.enc_struct(p.stype, p.sprop, b)
David Symonds4646c372013-09-09 13:18:58 +1000438 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700439 return err
440 }
441 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
David Symonds4646c372013-09-09 13:18:58 +1000442 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700443}
444
David Symonds0bf1ad52013-10-11 09:07:50 +1100445func size_struct_group(p *Properties, base structPointer) (n int) {
446 b := structPointer_GetStructPointer(base, p.field)
447 if structPointer_IsNil(b) {
448 return 0
449 }
450
451 n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
452 n += size_struct(p.stype, p.sprop, b)
453 n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
454 return
455}
456
Rob Pikeaaa3a622010-03-20 22:32:34 -0700457// Encode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000458func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
459 s := *structPointer_BoolSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700460 l := len(s)
461 if l == 0 {
462 return ErrNil
463 }
464 for _, x := range s {
Rob Pike99fa2b62010-12-02 10:39:42 -0800465 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000466 v := uint64(0)
467 if x {
468 v = 1
Rob Pikeaaa3a622010-03-20 22:32:34 -0700469 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000470 p.valEnc(o, v)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700471 }
472 return nil
473}
474
David Symonds0bf1ad52013-10-11 09:07:50 +1100475func size_slice_bool(p *Properties, base structPointer) int {
476 s := *structPointer_BoolSlice(base, p.field)
477 l := len(s)
478 if l == 0 {
479 return 0
480 }
481 return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
482}
483
David Symonds5b7775e2010-12-01 10:09:04 +1100484// Encode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000485func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
486 s := *structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100487 l := len(s)
488 if l == 0 {
489 return ErrNil
490 }
491 o.buf = append(o.buf, p.tagcode...)
492 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
493 for _, x := range s {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000494 v := uint64(0)
495 if x {
496 v = 1
David Symonds5b7775e2010-12-01 10:09:04 +1100497 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000498 p.valEnc(o, v)
David Symonds5b7775e2010-12-01 10:09:04 +1100499 }
500 return nil
501}
502
David Symonds0bf1ad52013-10-11 09:07:50 +1100503func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
504 s := *structPointer_BoolSlice(base, p.field)
505 l := len(s)
506 if l == 0 {
507 return 0
508 }
509 n += len(p.tagcode)
510 n += sizeVarint(uint64(l))
511 n += l // each bool takes exactly one byte
512 return
513}
514
Rob Pikeaaa3a622010-03-20 22:32:34 -0700515// Encode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000516func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
517 s := *structPointer_Bytes(base, p.field)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800518 if s == nil {
519 return ErrNil
520 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800521 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700522 o.EncodeRawBytes(s)
523 return nil
524}
525
David Symonds0bf1ad52013-10-11 09:07:50 +1100526func size_slice_byte(p *Properties, base structPointer) (n int) {
527 s := *structPointer_Bytes(base, p.field)
528 if s == nil {
529 return 0
530 }
531 n += len(p.tagcode)
532 n += sizeRawBytes(s)
533 return
534}
535
Rob Pikeaaa3a622010-03-20 22:32:34 -0700536// Encode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000537func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
538 s := structPointer_Word32Slice(base, p.field)
539 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700540 if l == 0 {
541 return ErrNil
542 }
543 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800544 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000545 x := s.Index(i)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700546 p.valEnc(o, uint64(x))
547 }
548 return nil
549}
550
David Symonds0bf1ad52013-10-11 09:07:50 +1100551func size_slice_int32(p *Properties, base structPointer) (n int) {
552 s := structPointer_Word32Slice(base, p.field)
553 l := s.Len()
554 if l == 0 {
555 return 0
556 }
557 for i := 0; i < l; i++ {
558 n += len(p.tagcode)
559 x := s.Index(i)
560 n += p.valSize(uint64(x))
561 }
562 return
563}
564
David Symonds5b7775e2010-12-01 10:09:04 +1100565// Encode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000566func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
567 s := structPointer_Word32Slice(base, p.field)
568 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100569 if l == 0 {
570 return ErrNil
571 }
572 // TODO: Reuse a Buffer.
573 buf := NewBuffer(nil)
574 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000575 p.valEnc(buf, uint64(s.Index(i)))
David Symonds5b7775e2010-12-01 10:09:04 +1100576 }
577
578 o.buf = append(o.buf, p.tagcode...)
579 o.EncodeVarint(uint64(len(buf.buf)))
580 o.buf = append(o.buf, buf.buf...)
581 return nil
582}
583
David Symonds0bf1ad52013-10-11 09:07:50 +1100584func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
585 s := structPointer_Word32Slice(base, p.field)
586 l := s.Len()
587 if l == 0 {
588 return 0
589 }
590 var bufSize int
591 for i := 0; i < l; i++ {
592 bufSize += p.valSize(uint64(s.Index(i)))
593 }
594
595 n += len(p.tagcode)
596 n += sizeVarint(uint64(bufSize))
597 n += bufSize
598 return
599}
600
Rob Pikeaaa3a622010-03-20 22:32:34 -0700601// Encode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000602func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
603 s := structPointer_Word64Slice(base, p.field)
604 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700605 if l == 0 {
606 return ErrNil
607 }
608 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800609 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000610 p.valEnc(o, s.Index(i))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700611 }
612 return nil
613}
614
David Symonds0bf1ad52013-10-11 09:07:50 +1100615func size_slice_int64(p *Properties, base structPointer) (n int) {
616 s := structPointer_Word64Slice(base, p.field)
617 l := s.Len()
618 if l == 0 {
619 return 0
620 }
621 for i := 0; i < l; i++ {
622 n += len(p.tagcode)
623 n += p.valSize(s.Index(i))
624 }
625 return
626}
627
David Symonds5b7775e2010-12-01 10:09:04 +1100628// Encode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000629func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
630 s := structPointer_Word64Slice(base, p.field)
631 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100632 if l == 0 {
633 return ErrNil
634 }
635 // TODO: Reuse a Buffer.
636 buf := NewBuffer(nil)
637 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000638 p.valEnc(buf, s.Index(i))
David Symonds5b7775e2010-12-01 10:09:04 +1100639 }
640
641 o.buf = append(o.buf, p.tagcode...)
642 o.EncodeVarint(uint64(len(buf.buf)))
643 o.buf = append(o.buf, buf.buf...)
644 return nil
645}
646
David Symonds0bf1ad52013-10-11 09:07:50 +1100647func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
648 s := structPointer_Word64Slice(base, p.field)
649 l := s.Len()
650 if l == 0 {
651 return 0
652 }
653 var bufSize int
654 for i := 0; i < l; i++ {
655 bufSize += p.valSize(s.Index(i))
656 }
657
658 n += len(p.tagcode)
659 n += sizeVarint(uint64(bufSize))
660 n += bufSize
661 return
662}
663
Rob Pikeaaa3a622010-03-20 22:32:34 -0700664// Encode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000665func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
666 ss := *structPointer_BytesSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700667 l := len(ss)
668 if l == 0 {
669 return ErrNil
670 }
671 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800672 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100673 o.EncodeRawBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700674 }
675 return nil
676}
677
David Symonds0bf1ad52013-10-11 09:07:50 +1100678func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
679 ss := *structPointer_BytesSlice(base, p.field)
680 l := len(ss)
681 if l == 0 {
682 return 0
683 }
684 n += l * len(p.tagcode)
685 for i := 0; i < l; i++ {
686 n += sizeRawBytes(ss[i])
687 }
688 return
689}
690
Rob Pikeaaa3a622010-03-20 22:32:34 -0700691// Encode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000692func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
693 ss := *structPointer_StringSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700694 l := len(ss)
695 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800696 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100697 o.EncodeStringBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700698 }
699 return nil
700}
701
David Symonds0bf1ad52013-10-11 09:07:50 +1100702func size_slice_string(p *Properties, base structPointer) (n int) {
703 ss := *structPointer_StringSlice(base, p.field)
704 l := len(ss)
705 n += l * len(p.tagcode)
706 for i := 0; i < l; i++ {
707 n += sizeStringBytes(ss[i])
708 }
709 return
710}
711
Rob Pikeaaa3a622010-03-20 22:32:34 -0700712// Encode a slice of message structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000713func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000714 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000715 s := structPointer_StructPointerSlice(base, p.field)
716 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700717
718 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000719 structp := s.Index(i)
720 if structPointer_IsNil(structp) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700721 return ErrRepeatedHasNil
722 }
723
724 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100725 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000726 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700727 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000728 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700729 return err
730 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800731 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700732 o.EncodeRawBytes(data)
733 continue
734 }
735
David Symonds1d8ba132014-01-13 16:01:15 +1100736 o.buf = append(o.buf, p.tagcode...)
737 err := o.enc_len_struct(p.stype, p.sprop, structp, &state)
David Symonds4646c372013-09-09 13:18:58 +1000738 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700739 if err == ErrNil {
740 return ErrRepeatedHasNil
741 }
742 return err
743 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700744 }
David Symonds4646c372013-09-09 13:18:58 +1000745 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700746}
747
David Symonds0bf1ad52013-10-11 09:07:50 +1100748func size_slice_struct_message(p *Properties, base structPointer) (n int) {
749 s := structPointer_StructPointerSlice(base, p.field)
750 l := s.Len()
751 n += l * len(p.tagcode)
752 for i := 0; i < l; i++ {
753 structp := s.Index(i)
754 if structPointer_IsNil(structp) {
755 return // return the size up to this point
756 }
757
758 // Can the object marshal itself?
759 if p.isMarshaler {
760 m := structPointer_Interface(structp, p.stype).(Marshaler)
761 data, _ := m.Marshal()
762 n += len(p.tagcode)
763 n += sizeRawBytes(data)
764 continue
765 }
766
767 n0 := size_struct(p.stype, p.sprop, structp)
768 n1 := sizeVarint(uint64(n0)) // size of encoded length
769 n += n0 + n1
770 }
771 return
772}
773
Rob Pikeaaa3a622010-03-20 22:32:34 -0700774// Encode a slice of group structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000775func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000776 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000777 s := structPointer_StructPointerSlice(base, p.field)
778 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700779
780 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000781 b := s.Index(i)
782 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700783 return ErrRepeatedHasNil
784 }
785
786 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
787
David Symonds6a6f82c2012-08-22 09:18:54 +1000788 err := o.enc_struct(p.stype, p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700789
David Symonds4646c372013-09-09 13:18:58 +1000790 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700791 if err == ErrNil {
792 return ErrRepeatedHasNil
793 }
794 return err
795 }
796
797 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
798 }
David Symonds4646c372013-09-09 13:18:58 +1000799 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700800}
801
David Symonds0bf1ad52013-10-11 09:07:50 +1100802func size_slice_struct_group(p *Properties, base structPointer) (n int) {
803 s := structPointer_StructPointerSlice(base, p.field)
804 l := s.Len()
805
806 n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
807 n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
808 for i := 0; i < l; i++ {
809 b := s.Index(i)
810 if structPointer_IsNil(b) {
811 return // return size up to this point
812 }
813
814 n += size_struct(p.stype, p.sprop, b)
815 }
816 return
817}
818
Rob Pikeaaa3a622010-03-20 22:32:34 -0700819// Encode an extension map.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000820func (o *Buffer) enc_map(p *Properties, base structPointer) error {
821 v := *structPointer_ExtMap(base, p.field)
David Symonds1d72f7a2011-08-19 18:28:52 +1000822 if err := encodeExtensionMap(v); err != nil {
823 return err
824 }
David Symondsdf583ae2012-12-06 14:06:53 +1100825 // Fast-path for common cases: zero or one extensions.
826 if len(v) <= 1 {
827 for _, e := range v {
828 o.buf = append(o.buf, e.enc...)
829 }
830 return nil
831 }
832
833 // Sort keys to provide a deterministic encoding.
834 keys := make([]int, 0, len(v))
835 for k := range v {
836 keys = append(keys, int(k))
837 }
838 sort.Ints(keys)
839
840 for _, k := range keys {
841 o.buf = append(o.buf, v[int32(k)].enc...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700842 }
843 return nil
844}
845
David Symonds0bf1ad52013-10-11 09:07:50 +1100846func size_map(p *Properties, base structPointer) int {
847 v := *structPointer_ExtMap(base, p.field)
848 return sizeExtensionMap(v)
849}
850
Rob Pikeaaa3a622010-03-20 22:32:34 -0700851// Encode a struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000852func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000853 var state errorState
David Symondsd15e81b2011-10-03 14:31:12 -0700854 // Encode fields in tag order so that decoders may use optimizations
855 // that depend on the ordering.
856 // http://code.google.com/apis/protocolbuffers/docs/encoding.html#order
857 for _, i := range prop.order {
858 p := prop.Prop[i]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700859 if p.enc != nil {
860 err := p.enc(o, p, base)
David Symonds4a2eeb52013-09-25 11:54:08 +1000861 if err != nil {
862 if err == ErrNil {
863 if p.Required && state.err == nil {
David Symondse583a5f2013-09-27 10:02:37 +1000864 state.err = &RequiredNotSetError{p.Name}
David Symonds4a2eeb52013-09-25 11:54:08 +1000865 }
866 } else if !state.shouldContinue(err, p) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700867 return err
868 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700869 }
870 }
871 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700872
David Symonds10c93ba2012-08-04 16:38:08 +1000873 // Add unrecognized fields at the end.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000874 if prop.unrecField.IsValid() {
875 v := *structPointer_Bytes(base, prop.unrecField)
876 if len(v) > 0 {
877 o.buf = append(o.buf, v...)
878 }
David Symonds10c93ba2012-08-04 16:38:08 +1000879 }
880
David Symonds4646c372013-09-09 13:18:58 +1000881 return state.err
882}
883
David Symonds0bf1ad52013-10-11 09:07:50 +1100884func size_struct(t reflect.Type, prop *StructProperties, base structPointer) (n int) {
885 for _, i := range prop.order {
886 p := prop.Prop[i]
887 if p.size != nil {
888 n += p.size(p, base)
889 }
890 }
891
892 // Add unrecognized fields at the end.
893 if prop.unrecField.IsValid() {
894 v := *structPointer_Bytes(base, prop.unrecField)
895 n += len(v)
896 }
897
898 return
899}
900
David Symonds1d8ba132014-01-13 16:01:15 +1100901var zeroes [20]byte // longer than any conceivable sizeVarint
902
903// Encode a struct, preceded by its encoded length (as a varint).
904func (o *Buffer) enc_len_struct(t reflect.Type, prop *StructProperties, base structPointer, state *errorState) error {
905 iLen := len(o.buf)
906 o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
907 iMsg := len(o.buf)
908 err := o.enc_struct(t, prop, base)
909 if err != nil && !state.shouldContinue(err, nil) {
910 return err
911 }
912 lMsg := len(o.buf) - iMsg
913 lLen := sizeVarint(uint64(lMsg))
914 switch x := lLen - (iMsg - iLen); {
915 case x > 0: // actual length is x bytes larger than the space we reserved
916 // Move msg x bytes right.
917 o.buf = append(o.buf, zeroes[:x]...)
918 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
919 case x < 0: // actual length is x bytes smaller than the space we reserved
920 // Move msg x bytes left.
921 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
922 o.buf = o.buf[:len(o.buf)+x] // x is negative
923 }
924 // Encode the length in the reserved space.
925 o.buf = o.buf[:iLen]
926 o.EncodeVarint(uint64(lMsg))
927 o.buf = o.buf[:len(o.buf)+lMsg]
928 return state.err
929}
930
David Symonds4646c372013-09-09 13:18:58 +1000931// errorState maintains the first error that occurs and updates that error
932// with additional context.
933type errorState struct {
934 err error
935}
936
937// shouldContinue reports whether encoding should continue upon encountering the
David Symondse583a5f2013-09-27 10:02:37 +1000938// given error. If the error is RequiredNotSetError, shouldContinue returns true
David Symonds4646c372013-09-09 13:18:58 +1000939// and, if this is the first appearance of that error, remembers it for future
940// reporting.
941//
942// If prop is not nil, it may update any error with additional context about the
943// field with the error.
944func (s *errorState) shouldContinue(err error, prop *Properties) bool {
945 // Ignore unset required fields.
David Symondse583a5f2013-09-27 10:02:37 +1000946 reqNotSet, ok := err.(*RequiredNotSetError)
David Symonds4646c372013-09-09 13:18:58 +1000947 if !ok {
948 return false
949 }
950 if s.err == nil {
951 if prop != nil {
David Symondse583a5f2013-09-27 10:02:37 +1000952 err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
David Symonds4646c372013-09-09 13:18:58 +1000953 }
954 s.err = err
955 }
956 return true
Rob Pikeaaa3a622010-03-20 22:32:34 -0700957}