blob: 1cc62e917c9c6dcc2c394bbbc9ecdb513717c037 [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
45// ErrRequiredNotSet is the error returned if Marshal is called with
46// 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//
51// When printed, ErrRequiredNotSet reports the first unset required field in a
52// message. If the field cannot be precisely determined, it is reported as
53// "{Unknown}".
David Symonds5b7775e2010-12-01 10:09:04 +110054type ErrRequiredNotSet struct {
David Symonds4646c372013-09-09 13:18:58 +100055 field string
David Symonds5b7775e2010-12-01 10:09:04 +110056}
57
Rob Pikea17fdd92011-11-02 12:43:05 -070058func (e *ErrRequiredNotSet) 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
108// EncodeFixed64 writes a 64-bit integer to the Buffer.
109// This is the format for the
110// fixed64, sfixed64, and double protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700111func (p *Buffer) EncodeFixed64(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000112 p.buf = append(p.buf,
113 uint8(x),
114 uint8(x>>8),
115 uint8(x>>16),
116 uint8(x>>24),
117 uint8(x>>32),
118 uint8(x>>40),
119 uint8(x>>48),
120 uint8(x>>56))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700121 return nil
122}
123
124// EncodeFixed32 writes a 32-bit integer to the Buffer.
125// This is the format for the
126// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700127func (p *Buffer) EncodeFixed32(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000128 p.buf = append(p.buf,
129 uint8(x),
130 uint8(x>>8),
131 uint8(x>>16),
132 uint8(x>>24))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700133 return nil
134}
135
136// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
137// to the Buffer.
138// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700139func (p *Buffer) EncodeZigzag64(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700140 // use signed number to get arithmetic right shift.
141 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
142}
143
144// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
145// to the Buffer.
146// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700147func (p *Buffer) EncodeZigzag32(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700148 // use signed number to get arithmetic right shift.
149 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
150}
151
152// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
153// This is the format used for the bytes protocol buffer
154// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700155func (p *Buffer) EncodeRawBytes(b []byte) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700156 p.EncodeVarint(uint64(len(b)))
Rob Pike99fa2b62010-12-02 10:39:42 -0800157 p.buf = append(p.buf, b...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700158 return nil
159}
160
161// EncodeStringBytes writes an encoded string to the Buffer.
162// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700163func (p *Buffer) EncodeStringBytes(s string) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700164 p.EncodeVarint(uint64(len(s)))
165 p.buf = append(p.buf, s...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700166 return nil
167}
168
169// Marshaler is the interface representing objects that can marshal themselves.
170type Marshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700171 Marshal() ([]byte, error)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700172}
173
David Symonds9f60f432012-06-14 09:45:25 +1000174// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700175// and encodes it into the wire format, returning the data.
David Symonds9f60f432012-06-14 09:45:25 +1000176func Marshal(pb Message) ([]byte, error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700177 // Can the object marshal itself?
178 if m, ok := pb.(Marshaler); ok {
179 return m.Marshal()
180 }
181 p := NewBuffer(nil)
182 err := p.Marshal(pb)
David Symonds4646c372013-09-09 13:18:58 +1000183 var state errorState
184 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700185 return nil, err
186 }
187 return p.buf, err
188}
189
David Symonds9f60f432012-06-14 09:45:25 +1000190// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700191// and encodes it into the wire format, writing the result to the
192// Buffer.
David Symonds9f60f432012-06-14 09:45:25 +1000193func (p *Buffer) Marshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700194 // Can the object marshal itself?
195 if m, ok := pb.(Marshaler); ok {
196 data, err := m.Marshal()
197 if err != nil {
198 return err
199 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800200 p.buf = append(p.buf, data...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700201 return nil
202 }
203
Russ Coxd4ce3f12012-09-12 10:36:26 +1000204 t, base, err := getbase(pb)
205 if structPointer_IsNil(base) {
David Symondsd4661c52012-08-30 15:17:53 +1000206 return ErrNil
207 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700208 if err == nil {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000209 err = p.enc_struct(t.Elem(), GetProperties(t.Elem()), base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700210 }
211
David Symonds9f60f432012-06-14 09:45:25 +1000212 if collectStats {
213 stats.Encode++
214 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700215
216 return err
217}
218
219// Individual type encoders.
220
221// Encode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000222func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
223 v := *structPointer_Bool(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700224 if v == nil {
225 return ErrNil
226 }
Rob Pike0f42a272011-10-20 16:03:11 -0700227 x := 0
228 if *v {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700229 x = 1
230 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800231 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700232 p.valEnc(o, uint64(x))
233 return nil
234}
235
236// Encode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000237func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
238 v := structPointer_Word32(base, p.field)
239 if word32_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700240 return ErrNil
241 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000242 x := word32_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800243 o.buf = append(o.buf, p.tagcode...)
David Symondsc31645c2013-06-22 17:57:36 +1000244 p.valEnc(o, uint64(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700245 return nil
246}
247
248// Encode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000249func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
250 v := structPointer_Word64(base, p.field)
251 if word64_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700252 return ErrNil
253 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000254 x := word64_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800255 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000256 p.valEnc(o, x)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700257 return nil
258}
259
260// Encode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000261func (o *Buffer) enc_string(p *Properties, base structPointer) error {
262 v := *structPointer_String(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700263 if v == nil {
264 return ErrNil
265 }
266 x := *v
Rob Pike99fa2b62010-12-02 10:39:42 -0800267 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700268 o.EncodeStringBytes(x)
269 return nil
270}
271
Rob Pike97e934d2011-04-11 12:52:49 -0700272// All protocol buffer fields are nillable, but be careful.
273func isNil(v reflect.Value) bool {
274 switch v.Kind() {
David Symonds007ed9d2012-07-24 10:59:36 +1000275 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
Rob Pike97e934d2011-04-11 12:52:49 -0700276 return v.IsNil()
277 }
278 return false
279}
280
Rob Pikeaaa3a622010-03-20 22:32:34 -0700281// Encode a message struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000282func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000283 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000284 structp := structPointer_GetStructPointer(base, p.field)
285 if structPointer_IsNil(structp) {
David Symondsa80b2822012-03-14 14:31:25 +1100286 return ErrNil
287 }
288
Rob Pikeaaa3a622010-03-20 22:32:34 -0700289 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100290 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000291 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700292 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000293 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700294 return err
295 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800296 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700297 o.EncodeRawBytes(data)
298 return nil
299 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700300
301 // need the length before we can write out the message itself,
302 // so marshal into a separate byte buffer first.
303 obuf := o.buf
304 o.buf = o.bufalloc()
305
Russ Coxd4ce3f12012-09-12 10:36:26 +1000306 err := o.enc_struct(p.stype, p.sprop, structp)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700307
308 nbuf := o.buf
309 o.buf = obuf
David Symonds4646c372013-09-09 13:18:58 +1000310 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700311 o.buffree(nbuf)
312 return err
313 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800314 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700315 o.EncodeRawBytes(nbuf)
316 o.buffree(nbuf)
David Symonds4646c372013-09-09 13:18:58 +1000317 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700318}
319
320// Encode a group struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000321func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000322 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000323 b := structPointer_GetStructPointer(base, p.field)
324 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700325 return ErrNil
326 }
327
328 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symonds6a6f82c2012-08-22 09:18:54 +1000329 err := o.enc_struct(p.stype, p.sprop, b)
David Symonds4646c372013-09-09 13:18:58 +1000330 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700331 return err
332 }
333 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
David Symonds4646c372013-09-09 13:18:58 +1000334 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700335}
336
337// Encode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000338func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
339 s := *structPointer_BoolSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700340 l := len(s)
341 if l == 0 {
342 return ErrNil
343 }
344 for _, x := range s {
Rob Pike99fa2b62010-12-02 10:39:42 -0800345 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000346 v := uint64(0)
347 if x {
348 v = 1
Rob Pikeaaa3a622010-03-20 22:32:34 -0700349 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000350 p.valEnc(o, v)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700351 }
352 return nil
353}
354
David Symonds5b7775e2010-12-01 10:09:04 +1100355// Encode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000356func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
357 s := *structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100358 l := len(s)
359 if l == 0 {
360 return ErrNil
361 }
362 o.buf = append(o.buf, p.tagcode...)
363 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
364 for _, x := range s {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000365 v := uint64(0)
366 if x {
367 v = 1
David Symonds5b7775e2010-12-01 10:09:04 +1100368 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000369 p.valEnc(o, v)
David Symonds5b7775e2010-12-01 10:09:04 +1100370 }
371 return nil
372}
373
Rob Pikeaaa3a622010-03-20 22:32:34 -0700374// Encode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000375func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
376 s := *structPointer_Bytes(base, p.field)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800377 if s == nil {
378 return ErrNil
379 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800380 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700381 o.EncodeRawBytes(s)
382 return nil
383}
384
385// Encode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000386func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
387 s := structPointer_Word32Slice(base, p.field)
388 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700389 if l == 0 {
390 return ErrNil
391 }
392 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800393 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000394 x := s.Index(i)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700395 p.valEnc(o, uint64(x))
396 }
397 return nil
398}
399
David Symonds5b7775e2010-12-01 10:09:04 +1100400// Encode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000401func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
402 s := structPointer_Word32Slice(base, p.field)
403 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100404 if l == 0 {
405 return ErrNil
406 }
407 // TODO: Reuse a Buffer.
408 buf := NewBuffer(nil)
409 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000410 p.valEnc(buf, uint64(s.Index(i)))
David Symonds5b7775e2010-12-01 10:09:04 +1100411 }
412
413 o.buf = append(o.buf, p.tagcode...)
414 o.EncodeVarint(uint64(len(buf.buf)))
415 o.buf = append(o.buf, buf.buf...)
416 return nil
417}
418
Rob Pikeaaa3a622010-03-20 22:32:34 -0700419// Encode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000420func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
421 s := structPointer_Word64Slice(base, p.field)
422 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700423 if l == 0 {
424 return ErrNil
425 }
426 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800427 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000428 p.valEnc(o, s.Index(i))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700429 }
430 return nil
431}
432
David Symonds5b7775e2010-12-01 10:09:04 +1100433// Encode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000434func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
435 s := structPointer_Word64Slice(base, p.field)
436 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100437 if l == 0 {
438 return ErrNil
439 }
440 // TODO: Reuse a Buffer.
441 buf := NewBuffer(nil)
442 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000443 p.valEnc(buf, s.Index(i))
David Symonds5b7775e2010-12-01 10:09:04 +1100444 }
445
446 o.buf = append(o.buf, p.tagcode...)
447 o.EncodeVarint(uint64(len(buf.buf)))
448 o.buf = append(o.buf, buf.buf...)
449 return nil
450}
451
Rob Pikeaaa3a622010-03-20 22:32:34 -0700452// Encode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000453func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
454 ss := *structPointer_BytesSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700455 l := len(ss)
456 if l == 0 {
457 return ErrNil
458 }
459 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800460 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700461 s := ss[i]
462 o.EncodeRawBytes(s)
463 }
464 return nil
465}
466
467// Encode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000468func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
469 ss := *structPointer_StringSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700470 l := len(ss)
471 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800472 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700473 s := ss[i]
474 o.EncodeStringBytes(s)
475 }
476 return nil
477}
478
479// Encode a slice of message structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000480func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000481 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000482 s := structPointer_StructPointerSlice(base, p.field)
483 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700484
485 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000486 structp := s.Index(i)
487 if structPointer_IsNil(structp) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700488 return ErrRepeatedHasNil
489 }
490
491 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100492 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000493 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700494 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000495 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700496 return err
497 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800498 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700499 o.EncodeRawBytes(data)
500 continue
501 }
502
503 obuf := o.buf
504 o.buf = o.bufalloc()
505
Russ Coxd4ce3f12012-09-12 10:36:26 +1000506 err := o.enc_struct(p.stype, p.sprop, structp)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700507
508 nbuf := o.buf
509 o.buf = obuf
David Symonds4646c372013-09-09 13:18:58 +1000510 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700511 o.buffree(nbuf)
512 if err == ErrNil {
513 return ErrRepeatedHasNil
514 }
515 return err
516 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800517 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700518 o.EncodeRawBytes(nbuf)
519
520 o.buffree(nbuf)
521 }
David Symonds4646c372013-09-09 13:18:58 +1000522 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700523}
524
525// Encode a slice of group structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000526func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000527 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000528 s := structPointer_StructPointerSlice(base, p.field)
529 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700530
531 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000532 b := s.Index(i)
533 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700534 return ErrRepeatedHasNil
535 }
536
537 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
538
David Symonds6a6f82c2012-08-22 09:18:54 +1000539 err := o.enc_struct(p.stype, p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700540
David Symonds4646c372013-09-09 13:18:58 +1000541 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700542 if err == ErrNil {
543 return ErrRepeatedHasNil
544 }
545 return err
546 }
547
548 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
549 }
David Symonds4646c372013-09-09 13:18:58 +1000550 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700551}
552
553// Encode an extension map.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000554func (o *Buffer) enc_map(p *Properties, base structPointer) error {
555 v := *structPointer_ExtMap(base, p.field)
David Symonds1d72f7a2011-08-19 18:28:52 +1000556 if err := encodeExtensionMap(v); err != nil {
557 return err
558 }
David Symondsdf583ae2012-12-06 14:06:53 +1100559 // Fast-path for common cases: zero or one extensions.
560 if len(v) <= 1 {
561 for _, e := range v {
562 o.buf = append(o.buf, e.enc...)
563 }
564 return nil
565 }
566
567 // Sort keys to provide a deterministic encoding.
568 keys := make([]int, 0, len(v))
569 for k := range v {
570 keys = append(keys, int(k))
571 }
572 sort.Ints(keys)
573
574 for _, k := range keys {
575 o.buf = append(o.buf, v[int32(k)].enc...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700576 }
577 return nil
578}
579
580// Encode a struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000581func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000582 var state errorState
David Symondsd15e81b2011-10-03 14:31:12 -0700583 // Encode fields in tag order so that decoders may use optimizations
584 // that depend on the ordering.
585 // http://code.google.com/apis/protocolbuffers/docs/encoding.html#order
586 for _, i := range prop.order {
587 p := prop.Prop[i]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700588 if p.enc != nil {
589 err := p.enc(o, p, base)
David Symonds4a2eeb52013-09-25 11:54:08 +1000590 if err != nil {
591 if err == ErrNil {
592 if p.Required && state.err == nil {
593 state.err = &ErrRequiredNotSet{p.Name}
594 }
595 } else if !state.shouldContinue(err, p) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700596 return err
597 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700598 }
599 }
600 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700601
David Symonds10c93ba2012-08-04 16:38:08 +1000602 // Add unrecognized fields at the end.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000603 if prop.unrecField.IsValid() {
604 v := *structPointer_Bytes(base, prop.unrecField)
605 if len(v) > 0 {
606 o.buf = append(o.buf, v...)
607 }
David Symonds10c93ba2012-08-04 16:38:08 +1000608 }
609
David Symonds4646c372013-09-09 13:18:58 +1000610 return state.err
611}
612
613// errorState maintains the first error that occurs and updates that error
614// with additional context.
615type errorState struct {
616 err error
617}
618
619// shouldContinue reports whether encoding should continue upon encountering the
620// given error. If the error is ErrRequiredNotSet, shouldContinue returns true
621// and, if this is the first appearance of that error, remembers it for future
622// reporting.
623//
624// If prop is not nil, it may update any error with additional context about the
625// field with the error.
626func (s *errorState) shouldContinue(err error, prop *Properties) bool {
627 // Ignore unset required fields.
628 reqNotSet, ok := err.(*ErrRequiredNotSet)
629 if !ok {
630 return false
631 }
632 if s.err == nil {
633 if prop != nil {
634 err = &ErrRequiredNotSet{prop.Name + "." + reqNotSet.field}
635 }
636 s.err = err
637 }
638 return true
Rob Pikeaaa3a622010-03-20 22:32:34 -0700639}