blob: 32401403b0d1de0003568de14e90c61cff08a016 [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// Go support for Protocol Buffers - Google's data interchange format
2//
3// Copyright 2010 Google Inc. All rights reserved.
4// 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"
Rob Pikeaaa3a622010-03-20 22:32:34 -070040 "reflect"
Rob Pikeaaa3a622010-03-20 22:32:34 -070041)
42
43// ErrRequiredNotSet is the error returned if Marshal is called with
44// a protocol buffer struct whose required fields have not
Rob Pikec6d8e4a2010-07-28 15:34:32 -070045// all been initialized. It is also the error returned if Unmarshal is
46// called with an encoded protocol buffer that does not include all the
47// required fields.
David Symonds5b7775e2010-12-01 10:09:04 +110048type ErrRequiredNotSet struct {
49 t reflect.Type
50}
51
Rob Pikea17fdd92011-11-02 12:43:05 -070052func (e *ErrRequiredNotSet) Error() string {
David Symonds7656e742011-07-22 14:54:17 +100053 return "proto: required fields not set in " + e.t.String()
David Symonds5b7775e2010-12-01 10:09:04 +110054}
Rob Pikeaaa3a622010-03-20 22:32:34 -070055
David Symonds7656e742011-07-22 14:54:17 +100056var (
57 // ErrRepeatedHasNil is the error returned if Marshal is called with
58 // a struct with a repeated field containing a nil element.
Rob Pikea17fdd92011-11-02 12:43:05 -070059 ErrRepeatedHasNil = errors.New("proto: repeated field has nil")
Rob Pikeaaa3a622010-03-20 22:32:34 -070060
David Symonds7656e742011-07-22 14:54:17 +100061 // ErrNil is the error returned if Marshal is called with nil.
Rob Pikea17fdd92011-11-02 12:43:05 -070062 ErrNil = errors.New("proto: Marshal called with nil")
David Symonds7656e742011-07-22 14:54:17 +100063)
Rob Pikeaaa3a622010-03-20 22:32:34 -070064
65// The fundamental encoders that put bytes on the wire.
66// Those that take integer types all accept uint64 and are
67// therefore of type valueEncoder.
68
David Symonds4fee3b12010-11-11 10:00:13 +110069const maxVarintBytes = 10 // maximum length of a varint
70
Rob Pikeaaa3a622010-03-20 22:32:34 -070071// EncodeVarint returns the varint encoding of x.
72// This is the format for the
73// int32, int64, uint32, uint64, bool, and enum
74// protocol buffer types.
75// Not used by the package itself, but helpful to clients
76// wishing to use the same encoding.
77func EncodeVarint(x uint64) []byte {
David Symonds4fee3b12010-11-11 10:00:13 +110078 var buf [maxVarintBytes]byte
Rob Pikeaaa3a622010-03-20 22:32:34 -070079 var n int
80 for n = 0; x > 127; n++ {
81 buf[n] = 0x80 | uint8(x&0x7F)
82 x >>= 7
83 }
84 buf[n] = uint8(x)
85 n++
86 return buf[0:n]
87}
88
89// EncodeVarint writes a varint-encoded integer to the Buffer.
90// This is the format for the
91// int32, int64, uint32, uint64, bool, and enum
92// protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -070093func (p *Buffer) EncodeVarint(x uint64) error {
David Symonds4fee3b12010-11-11 10:00:13 +110094 for x >= 1<<7 {
David Symondsd9da6ba2011-08-30 14:41:30 +100095 p.buf = append(p.buf, uint8(x&0x7f|0x80))
Rob Pikeaaa3a622010-03-20 22:32:34 -070096 x >>= 7
97 }
David Symondsd9da6ba2011-08-30 14:41:30 +100098 p.buf = append(p.buf, uint8(x))
Rob Pikeaaa3a622010-03-20 22:32:34 -070099 return nil
100}
101
102// EncodeFixed64 writes a 64-bit integer to the Buffer.
103// This is the format for the
104// fixed64, sfixed64, and double protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700105func (p *Buffer) EncodeFixed64(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000106 p.buf = append(p.buf,
107 uint8(x),
108 uint8(x>>8),
109 uint8(x>>16),
110 uint8(x>>24),
111 uint8(x>>32),
112 uint8(x>>40),
113 uint8(x>>48),
114 uint8(x>>56))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700115 return nil
116}
117
118// EncodeFixed32 writes a 32-bit integer to the Buffer.
119// This is the format for the
120// fixed32, sfixed32, and float protocol buffer types.
Rob Pikea17fdd92011-11-02 12:43:05 -0700121func (p *Buffer) EncodeFixed32(x uint64) error {
David Symondsd9da6ba2011-08-30 14:41:30 +1000122 p.buf = append(p.buf,
123 uint8(x),
124 uint8(x>>8),
125 uint8(x>>16),
126 uint8(x>>24))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700127 return nil
128}
129
130// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
131// to the Buffer.
132// This is the format used for the sint64 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700133func (p *Buffer) EncodeZigzag64(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700134 // use signed number to get arithmetic right shift.
135 return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
136}
137
138// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
139// to the Buffer.
140// This is the format used for the sint32 protocol buffer type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700141func (p *Buffer) EncodeZigzag32(x uint64) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700142 // use signed number to get arithmetic right shift.
143 return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
144}
145
146// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
147// This is the format used for the bytes protocol buffer
148// type and for embedded messages.
Rob Pikea17fdd92011-11-02 12:43:05 -0700149func (p *Buffer) EncodeRawBytes(b []byte) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700150 p.EncodeVarint(uint64(len(b)))
Rob Pike99fa2b62010-12-02 10:39:42 -0800151 p.buf = append(p.buf, b...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700152 return nil
153}
154
155// EncodeStringBytes writes an encoded string to the Buffer.
156// This is the format used for the proto2 string type.
Rob Pikea17fdd92011-11-02 12:43:05 -0700157func (p *Buffer) EncodeStringBytes(s string) error {
Rob Pike76f6ee52011-10-20 12:58:28 -0700158 p.EncodeVarint(uint64(len(s)))
159 p.buf = append(p.buf, s...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700160 return nil
161}
162
163// Marshaler is the interface representing objects that can marshal themselves.
164type Marshaler interface {
Rob Pikea17fdd92011-11-02 12:43:05 -0700165 Marshal() ([]byte, error)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700166}
167
David Symonds9f60f432012-06-14 09:45:25 +1000168// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700169// and encodes it into the wire format, returning the data.
David Symonds9f60f432012-06-14 09:45:25 +1000170func Marshal(pb Message) ([]byte, error) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700171 // Can the object marshal itself?
172 if m, ok := pb.(Marshaler); ok {
173 return m.Marshal()
174 }
175 p := NewBuffer(nil)
176 err := p.Marshal(pb)
177 if err != nil {
178 return nil, err
179 }
180 return p.buf, err
181}
182
David Symonds9f60f432012-06-14 09:45:25 +1000183// Marshal takes the protocol buffer
Rob Pikeaaa3a622010-03-20 22:32:34 -0700184// and encodes it into the wire format, writing the result to the
185// Buffer.
David Symonds9f60f432012-06-14 09:45:25 +1000186func (p *Buffer) Marshal(pb Message) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700187 // Can the object marshal itself?
188 if m, ok := pb.(Marshaler); ok {
189 data, err := m.Marshal()
190 if err != nil {
191 return err
192 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800193 p.buf = append(p.buf, data...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700194 return nil
195 }
196
Russ Coxd4ce3f12012-09-12 10:36:26 +1000197 t, base, err := getbase(pb)
198 if structPointer_IsNil(base) {
David Symondsd4661c52012-08-30 15:17:53 +1000199 return ErrNil
200 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700201 if err == nil {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000202 err = p.enc_struct(t.Elem(), GetProperties(t.Elem()), base)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700203 }
204
David Symonds9f60f432012-06-14 09:45:25 +1000205 if collectStats {
206 stats.Encode++
207 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700208
209 return err
210}
211
212// Individual type encoders.
213
214// Encode a bool.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000215func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
216 v := *structPointer_Bool(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700217 if v == nil {
218 return ErrNil
219 }
Rob Pike0f42a272011-10-20 16:03:11 -0700220 x := 0
221 if *v {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700222 x = 1
223 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800224 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700225 p.valEnc(o, uint64(x))
226 return nil
227}
228
229// Encode an int32.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000230func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
231 v := structPointer_Word32(base, p.field)
232 if word32_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700233 return ErrNil
234 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000235 x := word32_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800236 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000237 p.valEnc(o, uint64(int32(x)))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700238 return nil
239}
240
241// Encode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000242func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
243 v := structPointer_Word64(base, p.field)
244 if word64_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700245 return ErrNil
246 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000247 x := word64_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800248 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000249 p.valEnc(o, x)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700250 return nil
251}
252
253// Encode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000254func (o *Buffer) enc_string(p *Properties, base structPointer) error {
255 v := *structPointer_String(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700256 if v == nil {
257 return ErrNil
258 }
259 x := *v
Rob Pike99fa2b62010-12-02 10:39:42 -0800260 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700261 o.EncodeStringBytes(x)
262 return nil
263}
264
Rob Pike97e934d2011-04-11 12:52:49 -0700265// All protocol buffer fields are nillable, but be careful.
266func isNil(v reflect.Value) bool {
267 switch v.Kind() {
David Symonds007ed9d2012-07-24 10:59:36 +1000268 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
Rob Pike97e934d2011-04-11 12:52:49 -0700269 return v.IsNil()
270 }
271 return false
272}
273
Rob Pikeaaa3a622010-03-20 22:32:34 -0700274// Encode a message struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000275func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
276 structp := structPointer_GetStructPointer(base, p.field)
277 if structPointer_IsNil(structp) {
David Symondsa80b2822012-03-14 14:31:25 +1100278 return ErrNil
279 }
280
Rob Pikeaaa3a622010-03-20 22:32:34 -0700281 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100282 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000283 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700284 data, err := m.Marshal()
285 if err != nil {
286 return err
287 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800288 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700289 o.EncodeRawBytes(data)
290 return nil
291 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700292
293 // need the length before we can write out the message itself,
294 // so marshal into a separate byte buffer first.
295 obuf := o.buf
296 o.buf = o.bufalloc()
297
Russ Coxd4ce3f12012-09-12 10:36:26 +1000298 err := o.enc_struct(p.stype, p.sprop, structp)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700299
300 nbuf := o.buf
301 o.buf = obuf
302 if err != nil {
303 o.buffree(nbuf)
304 return err
305 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800306 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700307 o.EncodeRawBytes(nbuf)
308 o.buffree(nbuf)
309 return nil
310}
311
312// Encode a group struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000313func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
314 b := structPointer_GetStructPointer(base, p.field)
315 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700316 return ErrNil
317 }
318
319 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symonds6a6f82c2012-08-22 09:18:54 +1000320 err := o.enc_struct(p.stype, p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700321 if err != nil {
322 return err
323 }
324 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
325 return nil
326}
327
328// Encode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000329func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
330 s := *structPointer_BoolSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700331 l := len(s)
332 if l == 0 {
333 return ErrNil
334 }
335 for _, x := range s {
Rob Pike99fa2b62010-12-02 10:39:42 -0800336 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000337 v := uint64(0)
338 if x {
339 v = 1
Rob Pikeaaa3a622010-03-20 22:32:34 -0700340 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000341 p.valEnc(o, v)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700342 }
343 return nil
344}
345
David Symonds5b7775e2010-12-01 10:09:04 +1100346// Encode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000347func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
348 s := *structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100349 l := len(s)
350 if l == 0 {
351 return ErrNil
352 }
353 o.buf = append(o.buf, p.tagcode...)
354 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
355 for _, x := range s {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000356 v := uint64(0)
357 if x {
358 v = 1
David Symonds5b7775e2010-12-01 10:09:04 +1100359 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000360 p.valEnc(o, v)
David Symonds5b7775e2010-12-01 10:09:04 +1100361 }
362 return nil
363}
364
Rob Pikeaaa3a622010-03-20 22:32:34 -0700365// Encode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000366func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
367 s := *structPointer_Bytes(base, p.field)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800368 if s == nil {
369 return ErrNil
370 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800371 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700372 o.EncodeRawBytes(s)
373 return nil
374}
375
376// Encode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000377func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
378 s := structPointer_Word32Slice(base, p.field)
379 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700380 if l == 0 {
381 return ErrNil
382 }
383 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800384 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000385 x := s.Index(i)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700386 p.valEnc(o, uint64(x))
387 }
388 return nil
389}
390
David Symonds5b7775e2010-12-01 10:09:04 +1100391// Encode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000392func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
393 s := structPointer_Word32Slice(base, p.field)
394 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100395 if l == 0 {
396 return ErrNil
397 }
398 // TODO: Reuse a Buffer.
399 buf := NewBuffer(nil)
400 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000401 p.valEnc(buf, uint64(s.Index(i)))
David Symonds5b7775e2010-12-01 10:09:04 +1100402 }
403
404 o.buf = append(o.buf, p.tagcode...)
405 o.EncodeVarint(uint64(len(buf.buf)))
406 o.buf = append(o.buf, buf.buf...)
407 return nil
408}
409
Rob Pikeaaa3a622010-03-20 22:32:34 -0700410// Encode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000411func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
412 s := structPointer_Word64Slice(base, p.field)
413 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700414 if l == 0 {
415 return ErrNil
416 }
417 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800418 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000419 p.valEnc(o, s.Index(i))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700420 }
421 return nil
422}
423
David Symonds5b7775e2010-12-01 10:09:04 +1100424// Encode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000425func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
426 s := structPointer_Word64Slice(base, p.field)
427 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100428 if l == 0 {
429 return ErrNil
430 }
431 // TODO: Reuse a Buffer.
432 buf := NewBuffer(nil)
433 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000434 p.valEnc(buf, s.Index(i))
David Symonds5b7775e2010-12-01 10:09:04 +1100435 }
436
437 o.buf = append(o.buf, p.tagcode...)
438 o.EncodeVarint(uint64(len(buf.buf)))
439 o.buf = append(o.buf, buf.buf...)
440 return nil
441}
442
Rob Pikeaaa3a622010-03-20 22:32:34 -0700443// Encode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000444func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
445 ss := *structPointer_BytesSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700446 l := len(ss)
447 if l == 0 {
448 return ErrNil
449 }
450 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800451 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700452 s := ss[i]
453 o.EncodeRawBytes(s)
454 }
455 return nil
456}
457
458// Encode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000459func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
460 ss := *structPointer_StringSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700461 l := len(ss)
462 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800463 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700464 s := ss[i]
465 o.EncodeStringBytes(s)
466 }
467 return nil
468}
469
470// Encode a slice of message structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000471func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
472 s := structPointer_StructPointerSlice(base, p.field)
473 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700474
475 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000476 structp := s.Index(i)
477 if structPointer_IsNil(structp) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700478 return ErrRepeatedHasNil
479 }
480
481 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100482 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000483 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700484 data, err := m.Marshal()
485 if err != nil {
486 return err
487 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800488 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700489 o.EncodeRawBytes(data)
490 continue
491 }
492
493 obuf := o.buf
494 o.buf = o.bufalloc()
495
Russ Coxd4ce3f12012-09-12 10:36:26 +1000496 err := o.enc_struct(p.stype, p.sprop, structp)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700497
498 nbuf := o.buf
499 o.buf = obuf
500 if err != nil {
501 o.buffree(nbuf)
502 if err == ErrNil {
503 return ErrRepeatedHasNil
504 }
505 return err
506 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800507 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700508 o.EncodeRawBytes(nbuf)
509
510 o.buffree(nbuf)
511 }
512 return nil
513}
514
515// Encode a slice of group structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000516func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
517 s := structPointer_StructPointerSlice(base, p.field)
518 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700519
520 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000521 b := s.Index(i)
522 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700523 return ErrRepeatedHasNil
524 }
525
526 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
527
David Symonds6a6f82c2012-08-22 09:18:54 +1000528 err := o.enc_struct(p.stype, p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700529
530 if err != nil {
531 if err == ErrNil {
532 return ErrRepeatedHasNil
533 }
534 return err
535 }
536
537 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
538 }
539 return nil
540}
541
542// Encode an extension map.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000543func (o *Buffer) enc_map(p *Properties, base structPointer) error {
544 v := *structPointer_ExtMap(base, p.field)
David Symonds1d72f7a2011-08-19 18:28:52 +1000545 if err := encodeExtensionMap(v); err != nil {
546 return err
547 }
548 for _, e := range v {
549 o.buf = append(o.buf, e.enc...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700550 }
551 return nil
552}
553
554// Encode a struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000555func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700556 required := prop.reqCount
David Symondsd15e81b2011-10-03 14:31:12 -0700557 // Encode fields in tag order so that decoders may use optimizations
558 // that depend on the ordering.
559 // http://code.google.com/apis/protocolbuffers/docs/encoding.html#order
560 for _, i := range prop.order {
561 p := prop.Prop[i]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700562 if p.enc != nil {
563 err := p.enc(o, p, base)
564 if err != nil {
565 if err != ErrNil {
566 return err
567 }
568 } else if p.Required {
569 required--
570 }
571 }
572 }
573 // See if we encoded all required fields.
574 if required > 0 {
David Symonds5b7775e2010-12-01 10:09:04 +1100575 return &ErrRequiredNotSet{t}
Rob Pikeaaa3a622010-03-20 22:32:34 -0700576 }
577
David Symonds10c93ba2012-08-04 16:38:08 +1000578 // Add unrecognized fields at the end.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000579 if prop.unrecField.IsValid() {
580 v := *structPointer_Bytes(base, prop.unrecField)
581 if len(v) > 0 {
582 o.buf = append(o.buf, v...)
583 }
David Symonds10c93ba2012-08-04 16:38:08 +1000584 }
585
Rob Pikeaaa3a622010-03-20 22:32:34 -0700586 return nil
587}