blob: 2d3e03f6920ccc63ec3a1ea4323aa4b833bea220 [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 }
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 {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000250 err = p.enc_struct(t.Elem(), 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 {
274 n = size_struct(t.Elem(), GetProperties(t.Elem()), base)
275 }
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 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000315 x := word32_Get(v)
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 }
326 x := word32_Get(v)
327 n += len(p.tagcode)
328 n += p.valSize(uint64(x))
329 return
330}
331
Rob Pikeaaa3a622010-03-20 22:32:34 -0700332// Encode an int64.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000333func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
334 v := structPointer_Word64(base, p.field)
335 if word64_IsNil(v) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700336 return ErrNil
337 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000338 x := word64_Get(v)
Rob Pike99fa2b62010-12-02 10:39:42 -0800339 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000340 p.valEnc(o, x)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700341 return nil
342}
343
David Symonds0bf1ad52013-10-11 09:07:50 +1100344func size_int64(p *Properties, base structPointer) (n int) {
345 v := structPointer_Word64(base, p.field)
346 if word64_IsNil(v) {
347 return 0
348 }
349 x := word64_Get(v)
350 n += len(p.tagcode)
351 n += p.valSize(x)
352 return
353}
354
Rob Pikeaaa3a622010-03-20 22:32:34 -0700355// Encode a string.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000356func (o *Buffer) enc_string(p *Properties, base structPointer) error {
357 v := *structPointer_String(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700358 if v == nil {
359 return ErrNil
360 }
361 x := *v
Rob Pike99fa2b62010-12-02 10:39:42 -0800362 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700363 o.EncodeStringBytes(x)
364 return nil
365}
366
David Symonds0bf1ad52013-10-11 09:07:50 +1100367func size_string(p *Properties, base structPointer) (n int) {
368 v := *structPointer_String(base, p.field)
369 if v == nil {
370 return 0
371 }
372 x := *v
373 n += len(p.tagcode)
374 n += sizeStringBytes(x)
375 return
376}
377
Rob Pike97e934d2011-04-11 12:52:49 -0700378// All protocol buffer fields are nillable, but be careful.
379func isNil(v reflect.Value) bool {
380 switch v.Kind() {
David Symonds007ed9d2012-07-24 10:59:36 +1000381 case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
Rob Pike97e934d2011-04-11 12:52:49 -0700382 return v.IsNil()
383 }
384 return false
385}
386
Rob Pikeaaa3a622010-03-20 22:32:34 -0700387// Encode a message struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000388func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000389 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000390 structp := structPointer_GetStructPointer(base, p.field)
391 if structPointer_IsNil(structp) {
David Symondsa80b2822012-03-14 14:31:25 +1100392 return ErrNil
393 }
394
Rob Pikeaaa3a622010-03-20 22:32:34 -0700395 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100396 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000397 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700398 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000399 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700400 return err
401 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800402 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700403 o.EncodeRawBytes(data)
404 return nil
405 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700406
Rob Pike99fa2b62010-12-02 10:39:42 -0800407 o.buf = append(o.buf, p.tagcode...)
David Symonds1d8ba132014-01-13 16:01:15 +1100408 return o.enc_len_struct(p.stype, p.sprop, structp, &state)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700409}
410
David Symonds0bf1ad52013-10-11 09:07:50 +1100411func size_struct_message(p *Properties, base structPointer) int {
412 structp := structPointer_GetStructPointer(base, p.field)
413 if structPointer_IsNil(structp) {
414 return 0
415 }
416
417 // Can the object marshal itself?
418 if p.isMarshaler {
419 m := structPointer_Interface(structp, p.stype).(Marshaler)
420 data, _ := m.Marshal()
421 n0 := len(p.tagcode)
422 n1 := sizeRawBytes(data)
423 return n0 + n1
424 }
425
426 n0 := len(p.tagcode)
427 n1 := size_struct(p.stype, p.sprop, structp)
428 n2 := sizeVarint(uint64(n1)) // size of encoded length
429 return n0 + n1 + n2
430}
431
Rob Pikeaaa3a622010-03-20 22:32:34 -0700432// Encode a group struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000433func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000434 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000435 b := structPointer_GetStructPointer(base, p.field)
436 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700437 return ErrNil
438 }
439
440 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
David Symonds6a6f82c2012-08-22 09:18:54 +1000441 err := o.enc_struct(p.stype, p.sprop, b)
David Symonds4646c372013-09-09 13:18:58 +1000442 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700443 return err
444 }
445 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
David Symonds4646c372013-09-09 13:18:58 +1000446 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700447}
448
David Symonds0bf1ad52013-10-11 09:07:50 +1100449func size_struct_group(p *Properties, base structPointer) (n int) {
450 b := structPointer_GetStructPointer(base, p.field)
451 if structPointer_IsNil(b) {
452 return 0
453 }
454
455 n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
456 n += size_struct(p.stype, p.sprop, b)
457 n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
458 return
459}
460
Rob Pikeaaa3a622010-03-20 22:32:34 -0700461// Encode a slice of bools ([]bool).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000462func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
463 s := *structPointer_BoolSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700464 l := len(s)
465 if l == 0 {
466 return ErrNil
467 }
468 for _, x := range s {
Rob Pike99fa2b62010-12-02 10:39:42 -0800469 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000470 v := uint64(0)
471 if x {
472 v = 1
Rob Pikeaaa3a622010-03-20 22:32:34 -0700473 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000474 p.valEnc(o, v)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700475 }
476 return nil
477}
478
David Symonds0bf1ad52013-10-11 09:07:50 +1100479func size_slice_bool(p *Properties, base structPointer) int {
480 s := *structPointer_BoolSlice(base, p.field)
481 l := len(s)
482 if l == 0 {
483 return 0
484 }
485 return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
486}
487
David Symonds5b7775e2010-12-01 10:09:04 +1100488// Encode a slice of bools ([]bool) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000489func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
490 s := *structPointer_BoolSlice(base, p.field)
David Symonds5b7775e2010-12-01 10:09:04 +1100491 l := len(s)
492 if l == 0 {
493 return ErrNil
494 }
495 o.buf = append(o.buf, p.tagcode...)
496 o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
497 for _, x := range s {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000498 v := uint64(0)
499 if x {
500 v = 1
David Symonds5b7775e2010-12-01 10:09:04 +1100501 }
Russ Coxd4ce3f12012-09-12 10:36:26 +1000502 p.valEnc(o, v)
David Symonds5b7775e2010-12-01 10:09:04 +1100503 }
504 return nil
505}
506
David Symonds0bf1ad52013-10-11 09:07:50 +1100507func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
508 s := *structPointer_BoolSlice(base, p.field)
509 l := len(s)
510 if l == 0 {
511 return 0
512 }
513 n += len(p.tagcode)
514 n += sizeVarint(uint64(l))
515 n += l // each bool takes exactly one byte
516 return
517}
518
Rob Pikeaaa3a622010-03-20 22:32:34 -0700519// Encode a slice of bytes ([]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000520func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
521 s := *structPointer_Bytes(base, p.field)
Mikkel Krautzdb488aa2010-11-29 14:15:51 -0800522 if s == nil {
523 return ErrNil
524 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800525 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700526 o.EncodeRawBytes(s)
527 return nil
528}
529
David Symonds0bf1ad52013-10-11 09:07:50 +1100530func size_slice_byte(p *Properties, base structPointer) (n int) {
531 s := *structPointer_Bytes(base, p.field)
532 if s == nil {
533 return 0
534 }
535 n += len(p.tagcode)
536 n += sizeRawBytes(s)
537 return
538}
539
Rob Pikeaaa3a622010-03-20 22:32:34 -0700540// Encode a slice of int32s ([]int32).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000541func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
542 s := structPointer_Word32Slice(base, p.field)
543 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700544 if l == 0 {
545 return ErrNil
546 }
547 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800548 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000549 x := s.Index(i)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700550 p.valEnc(o, uint64(x))
551 }
552 return nil
553}
554
David Symonds0bf1ad52013-10-11 09:07:50 +1100555func size_slice_int32(p *Properties, base structPointer) (n int) {
556 s := structPointer_Word32Slice(base, p.field)
557 l := s.Len()
558 if l == 0 {
559 return 0
560 }
561 for i := 0; i < l; i++ {
562 n += len(p.tagcode)
563 x := s.Index(i)
564 n += p.valSize(uint64(x))
565 }
566 return
567}
568
David Symonds5b7775e2010-12-01 10:09:04 +1100569// Encode a slice of int32s ([]int32) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000570func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
571 s := structPointer_Word32Slice(base, p.field)
572 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100573 if l == 0 {
574 return ErrNil
575 }
576 // TODO: Reuse a Buffer.
577 buf := NewBuffer(nil)
578 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000579 p.valEnc(buf, uint64(s.Index(i)))
David Symonds5b7775e2010-12-01 10:09:04 +1100580 }
581
582 o.buf = append(o.buf, p.tagcode...)
583 o.EncodeVarint(uint64(len(buf.buf)))
584 o.buf = append(o.buf, buf.buf...)
585 return nil
586}
587
David Symonds0bf1ad52013-10-11 09:07:50 +1100588func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
589 s := structPointer_Word32Slice(base, p.field)
590 l := s.Len()
591 if l == 0 {
592 return 0
593 }
594 var bufSize int
595 for i := 0; i < l; i++ {
596 bufSize += p.valSize(uint64(s.Index(i)))
597 }
598
599 n += len(p.tagcode)
600 n += sizeVarint(uint64(bufSize))
601 n += bufSize
602 return
603}
604
Rob Pikeaaa3a622010-03-20 22:32:34 -0700605// Encode a slice of int64s ([]int64).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000606func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
607 s := structPointer_Word64Slice(base, p.field)
608 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700609 if l == 0 {
610 return ErrNil
611 }
612 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800613 o.buf = append(o.buf, p.tagcode...)
Russ Coxd4ce3f12012-09-12 10:36:26 +1000614 p.valEnc(o, s.Index(i))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700615 }
616 return nil
617}
618
David Symonds0bf1ad52013-10-11 09:07:50 +1100619func size_slice_int64(p *Properties, base structPointer) (n int) {
620 s := structPointer_Word64Slice(base, p.field)
621 l := s.Len()
622 if l == 0 {
623 return 0
624 }
625 for i := 0; i < l; i++ {
626 n += len(p.tagcode)
627 n += p.valSize(s.Index(i))
628 }
629 return
630}
631
David Symonds5b7775e2010-12-01 10:09:04 +1100632// Encode a slice of int64s ([]int64) in packed format.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000633func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
634 s := structPointer_Word64Slice(base, p.field)
635 l := s.Len()
David Symonds5b7775e2010-12-01 10:09:04 +1100636 if l == 0 {
637 return ErrNil
638 }
639 // TODO: Reuse a Buffer.
640 buf := NewBuffer(nil)
641 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000642 p.valEnc(buf, s.Index(i))
David Symonds5b7775e2010-12-01 10:09:04 +1100643 }
644
645 o.buf = append(o.buf, p.tagcode...)
646 o.EncodeVarint(uint64(len(buf.buf)))
647 o.buf = append(o.buf, buf.buf...)
648 return nil
649}
650
David Symonds0bf1ad52013-10-11 09:07:50 +1100651func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
652 s := structPointer_Word64Slice(base, p.field)
653 l := s.Len()
654 if l == 0 {
655 return 0
656 }
657 var bufSize int
658 for i := 0; i < l; i++ {
659 bufSize += p.valSize(s.Index(i))
660 }
661
662 n += len(p.tagcode)
663 n += sizeVarint(uint64(bufSize))
664 n += bufSize
665 return
666}
667
Rob Pikeaaa3a622010-03-20 22:32:34 -0700668// Encode a slice of slice of bytes ([][]byte).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000669func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
670 ss := *structPointer_BytesSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700671 l := len(ss)
672 if l == 0 {
673 return ErrNil
674 }
675 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800676 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100677 o.EncodeRawBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700678 }
679 return nil
680}
681
David Symonds0bf1ad52013-10-11 09:07:50 +1100682func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
683 ss := *structPointer_BytesSlice(base, p.field)
684 l := len(ss)
685 if l == 0 {
686 return 0
687 }
688 n += l * len(p.tagcode)
689 for i := 0; i < l; i++ {
690 n += sizeRawBytes(ss[i])
691 }
692 return
693}
694
Rob Pikeaaa3a622010-03-20 22:32:34 -0700695// Encode a slice of strings ([]string).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000696func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
697 ss := *structPointer_StringSlice(base, p.field)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700698 l := len(ss)
699 for i := 0; i < l; i++ {
Rob Pike99fa2b62010-12-02 10:39:42 -0800700 o.buf = append(o.buf, p.tagcode...)
David Symonds0bf1ad52013-10-11 09:07:50 +1100701 o.EncodeStringBytes(ss[i])
Rob Pikeaaa3a622010-03-20 22:32:34 -0700702 }
703 return nil
704}
705
David Symonds0bf1ad52013-10-11 09:07:50 +1100706func size_slice_string(p *Properties, base structPointer) (n int) {
707 ss := *structPointer_StringSlice(base, p.field)
708 l := len(ss)
709 n += l * len(p.tagcode)
710 for i := 0; i < l; i++ {
711 n += sizeStringBytes(ss[i])
712 }
713 return
714}
715
Rob Pikeaaa3a622010-03-20 22:32:34 -0700716// Encode a slice of message structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000717func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000718 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000719 s := structPointer_StructPointerSlice(base, p.field)
720 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700721
722 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000723 structp := s.Index(i)
724 if structPointer_IsNil(structp) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700725 return ErrRepeatedHasNil
726 }
727
728 // Can the object marshal itself?
David Symondsa80b2822012-03-14 14:31:25 +1100729 if p.isMarshaler {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000730 m := structPointer_Interface(structp, p.stype).(Marshaler)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700731 data, err := m.Marshal()
David Symonds4646c372013-09-09 13:18:58 +1000732 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700733 return err
734 }
Rob Pike99fa2b62010-12-02 10:39:42 -0800735 o.buf = append(o.buf, p.tagcode...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700736 o.EncodeRawBytes(data)
737 continue
738 }
739
David Symonds1d8ba132014-01-13 16:01:15 +1100740 o.buf = append(o.buf, p.tagcode...)
741 err := o.enc_len_struct(p.stype, p.sprop, structp, &state)
David Symonds4646c372013-09-09 13:18:58 +1000742 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700743 if err == ErrNil {
744 return ErrRepeatedHasNil
745 }
746 return err
747 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700748 }
David Symonds4646c372013-09-09 13:18:58 +1000749 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700750}
751
David Symonds0bf1ad52013-10-11 09:07:50 +1100752func size_slice_struct_message(p *Properties, base structPointer) (n int) {
753 s := structPointer_StructPointerSlice(base, p.field)
754 l := s.Len()
755 n += l * len(p.tagcode)
756 for i := 0; i < l; i++ {
757 structp := s.Index(i)
758 if structPointer_IsNil(structp) {
759 return // return the size up to this point
760 }
761
762 // Can the object marshal itself?
763 if p.isMarshaler {
764 m := structPointer_Interface(structp, p.stype).(Marshaler)
765 data, _ := m.Marshal()
766 n += len(p.tagcode)
767 n += sizeRawBytes(data)
768 continue
769 }
770
771 n0 := size_struct(p.stype, p.sprop, structp)
772 n1 := sizeVarint(uint64(n0)) // size of encoded length
773 n += n0 + n1
774 }
775 return
776}
777
Rob Pikeaaa3a622010-03-20 22:32:34 -0700778// Encode a slice of group structs ([]*struct).
Russ Coxd4ce3f12012-09-12 10:36:26 +1000779func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000780 var state errorState
Russ Coxd4ce3f12012-09-12 10:36:26 +1000781 s := structPointer_StructPointerSlice(base, p.field)
782 l := s.Len()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700783
784 for i := 0; i < l; i++ {
Russ Coxd4ce3f12012-09-12 10:36:26 +1000785 b := s.Index(i)
786 if structPointer_IsNil(b) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700787 return ErrRepeatedHasNil
788 }
789
790 o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
791
David Symonds6a6f82c2012-08-22 09:18:54 +1000792 err := o.enc_struct(p.stype, p.sprop, b)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700793
David Symonds4646c372013-09-09 13:18:58 +1000794 if err != nil && !state.shouldContinue(err, nil) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700795 if err == ErrNil {
796 return ErrRepeatedHasNil
797 }
798 return err
799 }
800
801 o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
802 }
David Symonds4646c372013-09-09 13:18:58 +1000803 return state.err
Rob Pikeaaa3a622010-03-20 22:32:34 -0700804}
805
David Symonds0bf1ad52013-10-11 09:07:50 +1100806func size_slice_struct_group(p *Properties, base structPointer) (n int) {
807 s := structPointer_StructPointerSlice(base, p.field)
808 l := s.Len()
809
810 n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
811 n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
812 for i := 0; i < l; i++ {
813 b := s.Index(i)
814 if structPointer_IsNil(b) {
815 return // return size up to this point
816 }
817
818 n += size_struct(p.stype, p.sprop, b)
819 }
820 return
821}
822
Rob Pikeaaa3a622010-03-20 22:32:34 -0700823// Encode an extension map.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000824func (o *Buffer) enc_map(p *Properties, base structPointer) error {
825 v := *structPointer_ExtMap(base, p.field)
David Symonds1d72f7a2011-08-19 18:28:52 +1000826 if err := encodeExtensionMap(v); err != nil {
827 return err
828 }
David Symondsdf583ae2012-12-06 14:06:53 +1100829 // Fast-path for common cases: zero or one extensions.
830 if len(v) <= 1 {
831 for _, e := range v {
832 o.buf = append(o.buf, e.enc...)
833 }
834 return nil
835 }
836
837 // Sort keys to provide a deterministic encoding.
838 keys := make([]int, 0, len(v))
839 for k := range v {
840 keys = append(keys, int(k))
841 }
842 sort.Ints(keys)
843
844 for _, k := range keys {
845 o.buf = append(o.buf, v[int32(k)].enc...)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700846 }
847 return nil
848}
849
David Symonds0bf1ad52013-10-11 09:07:50 +1100850func size_map(p *Properties, base structPointer) int {
851 v := *structPointer_ExtMap(base, p.field)
852 return sizeExtensionMap(v)
853}
854
Rob Pikeaaa3a622010-03-20 22:32:34 -0700855// Encode a struct.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000856func (o *Buffer) enc_struct(t reflect.Type, prop *StructProperties, base structPointer) error {
David Symonds4646c372013-09-09 13:18:58 +1000857 var state errorState
David Symondsd15e81b2011-10-03 14:31:12 -0700858 // Encode fields in tag order so that decoders may use optimizations
859 // that depend on the ordering.
860 // http://code.google.com/apis/protocolbuffers/docs/encoding.html#order
861 for _, i := range prop.order {
862 p := prop.Prop[i]
Rob Pikeaaa3a622010-03-20 22:32:34 -0700863 if p.enc != nil {
864 err := p.enc(o, p, base)
David Symonds4a2eeb52013-09-25 11:54:08 +1000865 if err != nil {
866 if err == ErrNil {
867 if p.Required && state.err == nil {
David Symondse583a5f2013-09-27 10:02:37 +1000868 state.err = &RequiredNotSetError{p.Name}
David Symonds4a2eeb52013-09-25 11:54:08 +1000869 }
870 } else if !state.shouldContinue(err, p) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700871 return err
872 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700873 }
874 }
875 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700876
David Symonds10c93ba2012-08-04 16:38:08 +1000877 // Add unrecognized fields at the end.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000878 if prop.unrecField.IsValid() {
879 v := *structPointer_Bytes(base, prop.unrecField)
880 if len(v) > 0 {
881 o.buf = append(o.buf, v...)
882 }
David Symonds10c93ba2012-08-04 16:38:08 +1000883 }
884
David Symonds4646c372013-09-09 13:18:58 +1000885 return state.err
886}
887
David Symonds0bf1ad52013-10-11 09:07:50 +1100888func size_struct(t reflect.Type, prop *StructProperties, base structPointer) (n int) {
889 for _, i := range prop.order {
890 p := prop.Prop[i]
891 if p.size != nil {
892 n += p.size(p, base)
893 }
894 }
895
896 // Add unrecognized fields at the end.
897 if prop.unrecField.IsValid() {
898 v := *structPointer_Bytes(base, prop.unrecField)
899 n += len(v)
900 }
901
902 return
903}
904
David Symonds1d8ba132014-01-13 16:01:15 +1100905var zeroes [20]byte // longer than any conceivable sizeVarint
906
907// Encode a struct, preceded by its encoded length (as a varint).
908func (o *Buffer) enc_len_struct(t reflect.Type, prop *StructProperties, base structPointer, state *errorState) error {
909 iLen := len(o.buf)
910 o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
911 iMsg := len(o.buf)
912 err := o.enc_struct(t, prop, base)
913 if err != nil && !state.shouldContinue(err, nil) {
914 return err
915 }
916 lMsg := len(o.buf) - iMsg
917 lLen := sizeVarint(uint64(lMsg))
918 switch x := lLen - (iMsg - iLen); {
919 case x > 0: // actual length is x bytes larger than the space we reserved
920 // Move msg x bytes right.
921 o.buf = append(o.buf, zeroes[:x]...)
922 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
923 case x < 0: // actual length is x bytes smaller than the space we reserved
924 // Move msg x bytes left.
925 copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
926 o.buf = o.buf[:len(o.buf)+x] // x is negative
927 }
928 // Encode the length in the reserved space.
929 o.buf = o.buf[:iLen]
930 o.EncodeVarint(uint64(lMsg))
931 o.buf = o.buf[:len(o.buf)+lMsg]
932 return state.err
933}
934
David Symonds4646c372013-09-09 13:18:58 +1000935// errorState maintains the first error that occurs and updates that error
936// with additional context.
937type errorState struct {
938 err error
939}
940
941// shouldContinue reports whether encoding should continue upon encountering the
David Symondse583a5f2013-09-27 10:02:37 +1000942// given error. If the error is RequiredNotSetError, shouldContinue returns true
David Symonds4646c372013-09-09 13:18:58 +1000943// and, if this is the first appearance of that error, remembers it for future
944// reporting.
945//
946// If prop is not nil, it may update any error with additional context about the
947// field with the error.
948func (s *errorState) shouldContinue(err error, prop *Properties) bool {
949 // Ignore unset required fields.
David Symondse583a5f2013-09-27 10:02:37 +1000950 reqNotSet, ok := err.(*RequiredNotSetError)
David Symonds4646c372013-09-09 13:18:58 +1000951 if !ok {
952 return false
953 }
954 if s.err == nil {
955 if prop != nil {
David Symondse583a5f2013-09-27 10:02:37 +1000956 err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
David Symonds4646c372013-09-09 13:18:58 +1000957 }
958 s.err = err
959 }
960 return true
Rob Pikeaaa3a622010-03-20 22:32:34 -0700961}