1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville"""Constants and static functions to support protocol buffer wire format."""
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville__author__ = 'robinson@google.com (Will Robinson)'
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport struct
36d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillefrom google.protobuf import descriptor
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf import message
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTAG_TYPE_BITS = 3  # Number of bits used to hold type info in a proto tag.
41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1  # 0x7
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# These numbers identify the wire type of a protocol buffer value.
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# tag-and-type to store one of these WIRETYPE_* constants.
46d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville# These values must match WireType enum in google/protobuf/wire_format.h.
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleWIRETYPE_VARINT = 0
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleWIRETYPE_FIXED64 = 1
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleWIRETYPE_LENGTH_DELIMITED = 2
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleWIRETYPE_START_GROUP = 3
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleWIRETYPE_END_GROUP = 4
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleWIRETYPE_FIXED32 = 5
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville_WIRETYPE_MAX = 5
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Bounds for various integer types.
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleINT32_MAX = int((1 << 31) - 1)
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleINT32_MIN = int(-(1 << 31))
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleUINT32_MAX = (1 << 32) - 1
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleINT64_MAX = (1 << 63) - 1
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleINT64_MIN = -(1 << 63)
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleUINT64_MAX = (1 << 64) - 1
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# "struct" format strings that will encode/decode the specified formats.
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFORMAT_UINT32_LITTLE_ENDIAN = '<I'
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFORMAT_UINT64_LITTLE_ENDIAN = '<Q'
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFORMAT_FLOAT_LITTLE_ENDIAN = '<f'
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFORMAT_DOUBLE_LITTLE_ENDIAN = '<d'
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# We'll have to provide alternate implementations of AppendLittleEndian*() on
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# any architectures where these checks fail.
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleif struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4:
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  raise AssertionError('Format "I" is not a 32-bit number.')
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleif struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8:
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  raise AssertionError('Format "Q" is not a 64-bit number.')
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef PackTag(field_number, wire_type):
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns an unsigned 32-bit integer that encodes the field number and
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  wire type information in standard protocol message wire format.
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Args:
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_number: Expected to be an integer in the range [1, 1 << 29)
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    wire_type: One of the WIRETYPE_* constants.
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if not 0 <= wire_type <= _WIRETYPE_MAX:
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    raise message.EncodeError('Unknown wire type: %d' % wire_type)
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return (field_number << TAG_TYPE_BITS) | wire_type
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef UnpackTag(tag):
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """The inverse of PackTag().  Given an unsigned 32-bit number,
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  returns a (field_number, wire_type) tuple.
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """
97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return (tag >> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK)
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef ZigZagEncode(value):
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """ZigZag Transform:  Encodes signed integers so that they can be
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  effectively used with varint encoding.  See wire_format.h for
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  more details.
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if value >= 0:
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return value << 1
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return (value << 1) ^ (~0)
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef ZigZagDecode(value):
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Inverse of ZigZagEncode()."""
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if not value & 0x1:
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return value >> 1
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return (value >> 1) ^ (~0)
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# The *ByteSize() functions below return the number of bytes required to
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# serialize "field number + type" information and then serialize the value.
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef Int32ByteSize(field_number, int32):
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return Int64ByteSize(field_number, int32)
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef Int32ByteSizeNoTag(int32):
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32)
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef Int64ByteSize(field_number, int64):
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # Have to convert to uint before calling UInt64ByteSize().
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UInt64ByteSize(field_number, 0xffffffffffffffff & int64)
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef UInt32ByteSize(field_number, uint32):
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UInt64ByteSize(field_number, uint32)
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef UInt64ByteSize(field_number, uint64):
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef SInt32ByteSize(field_number, int32):
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UInt32ByteSize(field_number, ZigZagEncode(int32))
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef SInt64ByteSize(field_number, int64):
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UInt64ByteSize(field_number, ZigZagEncode(int64))
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef Fixed32ByteSize(field_number, fixed32):
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + 4
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef Fixed64ByteSize(field_number, fixed64):
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + 8
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef SFixed32ByteSize(field_number, sfixed32):
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + 4
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef SFixed64ByteSize(field_number, sfixed64):
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + 8
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef FloatByteSize(field_number, flt):
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + 4
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef DoubleByteSize(field_number, double):
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + 8
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef BoolByteSize(field_number, b):
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return TagByteSize(field_number) + 1
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef EnumByteSize(field_number, enum):
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return UInt32ByteSize(field_number, enum)
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef StringByteSize(field_number, string):
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return BytesByteSize(field_number, string.encode('utf-8'))
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef BytesByteSize(field_number, b):
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return (TagByteSize(field_number)
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          + _VarUInt64ByteSizeNoTag(len(b))
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          + len(b))
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef GroupByteSize(field_number, message):
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return (2 * TagByteSize(field_number)  # START and END group.
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          + message.ByteSize())
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef MessageByteSize(field_number, message):
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return (TagByteSize(field_number)
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          + _VarUInt64ByteSizeNoTag(message.ByteSize())
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          + message.ByteSize())
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef MessageSetItemByteSize(field_number, msg):
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # First compute the sizes of the tags.
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # There are 2 tags for the beginning and ending of the repeated group, that
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # is field number 1, one with field number 2 (type_id) and one with field
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # number 3 (message).
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3))
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # Add the number of bytes for type_id.
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  total_size += _VarUInt64ByteSizeNoTag(field_number)
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  message_size = msg.ByteSize()
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # The number of bytes for encoding the length of the message.
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  total_size += _VarUInt64ByteSizeNoTag(message_size)
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # The size of the message.
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  total_size += message_size
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return total_size
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef TagByteSize(field_number):
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns the bytes required to serialize a tag with this field number."""
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # Just pass in type 0, since the type won't affect the tag+type size.
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0))
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Private helper function for the *ByteSize() functions above.
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _VarUInt64ByteSizeNoTag(uint64):
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns the number of bytes required to serialize a single varint
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  using boundary value comparisons. (unrolled loop optimization -WPierce)
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint64 must be unsigned.
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0x7f: return 1
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0x3fff: return 2
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0x1fffff: return 3
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0xfffffff: return 4
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0x7ffffffff: return 5
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0x3ffffffffff: return 6
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0x1ffffffffffff: return 7
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0xffffffffffffff: return 8
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 <= 0x7fffffffffffffff: return 9
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if uint64 > UINT64_MAX:
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    raise message.EncodeError('Value out of range: %d' % uint64)
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return 10
249d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
250d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleNON_PACKABLE_TYPES = (
252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  descriptor.FieldDescriptor.TYPE_STRING,
253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  descriptor.FieldDescriptor.TYPE_GROUP,
254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  descriptor.FieldDescriptor.TYPE_MESSAGE,
255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  descriptor.FieldDescriptor.TYPE_BYTES
256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville)
257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
258d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
259d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef IsTypePackable(field_type):
260d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  """Return true iff packable = true is valid for fields of this type.
261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  Args:
263d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    field_type: a FieldDescriptor::Type value.
264d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
265d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  Returns:
266d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    True iff fields of this type are packable.
267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  """
268d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return field_type not in NON_PACKABLE_TYPES
269