1// Protocol Buffers for Go with Gadgets
2//
3// Copyright (c) 2013, The GoGo Authors. All rights reserved.
4// http://github.com/gogo/protobuf
5//
6// Go support for Protocol Buffers - Google's data interchange format
7//
8// Copyright 2010 The Go Authors.  All rights reserved.
9// http://github.com/golang/protobuf/
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15//     * Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//     * Redistributions in binary form must reproduce the above
18// copyright notice, this list of conditions and the following disclaimer
19// in the documentation and/or other materials provided with the
20// distribution.
21//     * Neither the name of Google Inc. nor the names of its
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
37package proto
38
39import (
40	"reflect"
41)
42
43func NewRequiredNotSetError(field string) *RequiredNotSetError {
44	return &RequiredNotSetError{field}
45}
46
47type Sizer interface {
48	Size() int
49}
50
51func (o *Buffer) enc_ext_slice_byte(p *Properties, base structPointer) error {
52	s := *structPointer_Bytes(base, p.field)
53	if s == nil {
54		return ErrNil
55	}
56	o.buf = append(o.buf, s...)
57	return nil
58}
59
60func size_ext_slice_byte(p *Properties, base structPointer) (n int) {
61	s := *structPointer_Bytes(base, p.field)
62	if s == nil {
63		return 0
64	}
65	n += len(s)
66	return
67}
68
69// Encode a reference to bool pointer.
70func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
71	v := *structPointer_BoolVal(base, p.field)
72	x := 0
73	if v {
74		x = 1
75	}
76	o.buf = append(o.buf, p.tagcode...)
77	p.valEnc(o, uint64(x))
78	return nil
79}
80
81func size_ref_bool(p *Properties, base structPointer) int {
82	return len(p.tagcode) + 1 // each bool takes exactly one byte
83}
84
85// Encode a reference to int32 pointer.
86func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
87	v := structPointer_Word32Val(base, p.field)
88	x := int32(word32Val_Get(v))
89	o.buf = append(o.buf, p.tagcode...)
90	p.valEnc(o, uint64(x))
91	return nil
92}
93
94func size_ref_int32(p *Properties, base structPointer) (n int) {
95	v := structPointer_Word32Val(base, p.field)
96	x := int32(word32Val_Get(v))
97	n += len(p.tagcode)
98	n += p.valSize(uint64(x))
99	return
100}
101
102func (o *Buffer) enc_ref_uint32(p *Properties, base structPointer) error {
103	v := structPointer_Word32Val(base, p.field)
104	x := word32Val_Get(v)
105	o.buf = append(o.buf, p.tagcode...)
106	p.valEnc(o, uint64(x))
107	return nil
108}
109
110func size_ref_uint32(p *Properties, base structPointer) (n int) {
111	v := structPointer_Word32Val(base, p.field)
112	x := word32Val_Get(v)
113	n += len(p.tagcode)
114	n += p.valSize(uint64(x))
115	return
116}
117
118// Encode a reference to an int64 pointer.
119func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
120	v := structPointer_Word64Val(base, p.field)
121	x := word64Val_Get(v)
122	o.buf = append(o.buf, p.tagcode...)
123	p.valEnc(o, x)
124	return nil
125}
126
127func size_ref_int64(p *Properties, base structPointer) (n int) {
128	v := structPointer_Word64Val(base, p.field)
129	x := word64Val_Get(v)
130	n += len(p.tagcode)
131	n += p.valSize(x)
132	return
133}
134
135// Encode a reference to a string pointer.
136func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
137	v := *structPointer_StringVal(base, p.field)
138	o.buf = append(o.buf, p.tagcode...)
139	o.EncodeStringBytes(v)
140	return nil
141}
142
143func size_ref_string(p *Properties, base structPointer) (n int) {
144	v := *structPointer_StringVal(base, p.field)
145	n += len(p.tagcode)
146	n += sizeStringBytes(v)
147	return
148}
149
150// Encode a reference to a message struct.
151func (o *Buffer) enc_ref_struct_message(p *Properties, base structPointer) error {
152	var state errorState
153	structp := structPointer_GetRefStructPointer(base, p.field)
154	if structPointer_IsNil(structp) {
155		return ErrNil
156	}
157
158	// Can the object marshal itself?
159	if p.isMarshaler {
160		m := structPointer_Interface(structp, p.stype).(Marshaler)
161		data, err := m.Marshal()
162		if err != nil && !state.shouldContinue(err, nil) {
163			return err
164		}
165		o.buf = append(o.buf, p.tagcode...)
166		o.EncodeRawBytes(data)
167		return nil
168	}
169
170	o.buf = append(o.buf, p.tagcode...)
171	return o.enc_len_struct(p.sprop, structp, &state)
172}
173
174//TODO this is only copied, please fix this
175func size_ref_struct_message(p *Properties, base structPointer) int {
176	structp := structPointer_GetRefStructPointer(base, p.field)
177	if structPointer_IsNil(structp) {
178		return 0
179	}
180
181	// Can the object marshal itself?
182	if p.isMarshaler {
183		m := structPointer_Interface(structp, p.stype).(Marshaler)
184		data, _ := m.Marshal()
185		n0 := len(p.tagcode)
186		n1 := sizeRawBytes(data)
187		return n0 + n1
188	}
189
190	n0 := len(p.tagcode)
191	n1 := size_struct(p.sprop, structp)
192	n2 := sizeVarint(uint64(n1)) // size of encoded length
193	return n0 + n1 + n2
194}
195
196// Encode a slice of references to message struct pointers ([]struct).
197func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error {
198	var state errorState
199	ss := structPointer_StructRefSlice(base, p.field, p.stype.Size())
200	l := ss.Len()
201	for i := 0; i < l; i++ {
202		structp := ss.Index(i)
203		if structPointer_IsNil(structp) {
204			return errRepeatedHasNil
205		}
206
207		// Can the object marshal itself?
208		if p.isMarshaler {
209			m := structPointer_Interface(structp, p.stype).(Marshaler)
210			data, err := m.Marshal()
211			if err != nil && !state.shouldContinue(err, nil) {
212				return err
213			}
214			o.buf = append(o.buf, p.tagcode...)
215			o.EncodeRawBytes(data)
216			continue
217		}
218
219		o.buf = append(o.buf, p.tagcode...)
220		err := o.enc_len_struct(p.sprop, structp, &state)
221		if err != nil && !state.shouldContinue(err, nil) {
222			if err == ErrNil {
223				return errRepeatedHasNil
224			}
225			return err
226		}
227
228	}
229	return state.err
230}
231
232//TODO this is only copied, please fix this
233func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) {
234	ss := structPointer_StructRefSlice(base, p.field, p.stype.Size())
235	l := ss.Len()
236	n += l * len(p.tagcode)
237	for i := 0; i < l; i++ {
238		structp := ss.Index(i)
239		if structPointer_IsNil(structp) {
240			return // return the size up to this point
241		}
242
243		// Can the object marshal itself?
244		if p.isMarshaler {
245			m := structPointer_Interface(structp, p.stype).(Marshaler)
246			data, _ := m.Marshal()
247			n += len(p.tagcode)
248			n += sizeRawBytes(data)
249			continue
250		}
251
252		n0 := size_struct(p.sprop, structp)
253		n1 := sizeVarint(uint64(n0)) // size of encoded length
254		n += n0 + n1
255	}
256	return
257}
258
259func (o *Buffer) enc_custom_bytes(p *Properties, base structPointer) error {
260	i := structPointer_InterfaceRef(base, p.field, p.ctype)
261	if i == nil {
262		return ErrNil
263	}
264	custom := i.(Marshaler)
265	data, err := custom.Marshal()
266	if err != nil {
267		return err
268	}
269	if data == nil {
270		return ErrNil
271	}
272	o.buf = append(o.buf, p.tagcode...)
273	o.EncodeRawBytes(data)
274	return nil
275}
276
277func size_custom_bytes(p *Properties, base structPointer) (n int) {
278	n += len(p.tagcode)
279	i := structPointer_InterfaceRef(base, p.field, p.ctype)
280	if i == nil {
281		return 0
282	}
283	custom := i.(Marshaler)
284	data, _ := custom.Marshal()
285	n += sizeRawBytes(data)
286	return
287}
288
289func (o *Buffer) enc_custom_ref_bytes(p *Properties, base structPointer) error {
290	custom := structPointer_InterfaceAt(base, p.field, p.ctype).(Marshaler)
291	data, err := custom.Marshal()
292	if err != nil {
293		return err
294	}
295	if data == nil {
296		return ErrNil
297	}
298	o.buf = append(o.buf, p.tagcode...)
299	o.EncodeRawBytes(data)
300	return nil
301}
302
303func size_custom_ref_bytes(p *Properties, base structPointer) (n int) {
304	n += len(p.tagcode)
305	i := structPointer_InterfaceAt(base, p.field, p.ctype)
306	if i == nil {
307		return 0
308	}
309	custom := i.(Marshaler)
310	data, _ := custom.Marshal()
311	n += sizeRawBytes(data)
312	return
313}
314
315func (o *Buffer) enc_custom_slice_bytes(p *Properties, base structPointer) error {
316	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
317	if inter == nil {
318		return ErrNil
319	}
320	slice := reflect.ValueOf(inter)
321	l := slice.Len()
322	for i := 0; i < l; i++ {
323		v := slice.Index(i)
324		custom := v.Interface().(Marshaler)
325		data, err := custom.Marshal()
326		if err != nil {
327			return err
328		}
329		o.buf = append(o.buf, p.tagcode...)
330		o.EncodeRawBytes(data)
331	}
332	return nil
333}
334
335func size_custom_slice_bytes(p *Properties, base structPointer) (n int) {
336	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
337	if inter == nil {
338		return 0
339	}
340	slice := reflect.ValueOf(inter)
341	l := slice.Len()
342	n += l * len(p.tagcode)
343	for i := 0; i < l; i++ {
344		v := slice.Index(i)
345		custom := v.Interface().(Marshaler)
346		data, _ := custom.Marshal()
347		n += sizeRawBytes(data)
348	}
349	return
350}
351