protobuf/python/google/protobuf/internal/encoder.py
Go to the documentation of this file.
1 # Protocol Buffers - Google's data interchange format
2 # Copyright 2008 Google Inc. All rights reserved.
3 # https://developers.google.com/protocol-buffers/
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 """Code for encoding protocol message primitives.
32 
33 Contains the logic for encoding every logical protocol field type
34 into one of the 5 physical wire types.
35 
36 This code is designed to push the Python interpreter's performance to the
37 limits.
38 
39 The basic idea is that at startup time, for every field (i.e. every
40 FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The
41 sizer takes a value of this field's type and computes its byte size. The
42 encoder takes a writer function and a value. It encodes the value into byte
43 strings and invokes the writer function to write those strings. Typically the
44 writer function is the write() method of a BytesIO.
45 
46 We try to do as much work as possible when constructing the writer and the
47 sizer rather than when calling them. In particular:
48 * We copy any needed global functions to local variables, so that we do not need
49  to do costly global table lookups at runtime.
50 * Similarly, we try to do any attribute lookups at startup time if possible.
51 * Every field's tag is encoded to bytes at startup, since it can't change at
52  runtime.
53 * Whatever component of the field size we can compute at startup, we do.
54 * We *avoid* sharing code if doing so would make the code slower and not sharing
55  does not burden us too much. For example, encoders for repeated fields do
56  not just call the encoders for singular fields in a loop because this would
57  add an extra function call overhead for every loop iteration; instead, we
58  manually inline the single-value encoder into the loop.
59 * If a Python function lacks a return statement, Python actually generates
60  instructions to pop the result of the last statement off the stack, push
61  None onto the stack, and then return that. If we really don't care what
62  value is returned, then we can save two instructions by returning the
63  result of the last statement. It looks funny but it helps.
64 * We assume that type and bounds checking has happened at a higher level.
65 """
66 
67 __author__ = 'kenton@google.com (Kenton Varda)'
68 
69 import struct
70 
71 from google.protobuf.internal import wire_format
72 
73 
74 # This will overflow and thus become IEEE-754 "infinity". We would use
75 # "float('inf')" but it doesn't work on Windows pre-Python-2.6.
76 _POS_INF = 1e10000
77 _NEG_INF = -_POS_INF
78 
79 
80 def _VarintSize(value):
81  """Compute the size of a varint value."""
82  if value <= 0x7f: return 1
83  if value <= 0x3fff: return 2
84  if value <= 0x1fffff: return 3
85  if value <= 0xfffffff: return 4
86  if value <= 0x7ffffffff: return 5
87  if value <= 0x3ffffffffff: return 6
88  if value <= 0x1ffffffffffff: return 7
89  if value <= 0xffffffffffffff: return 8
90  if value <= 0x7fffffffffffffff: return 9
91  return 10
92 
93 
94 def _SignedVarintSize(value):
95  """Compute the size of a signed varint value."""
96  if value < 0: return 10
97  if value <= 0x7f: return 1
98  if value <= 0x3fff: return 2
99  if value <= 0x1fffff: return 3
100  if value <= 0xfffffff: return 4
101  if value <= 0x7ffffffff: return 5
102  if value <= 0x3ffffffffff: return 6
103  if value <= 0x1ffffffffffff: return 7
104  if value <= 0xffffffffffffff: return 8
105  if value <= 0x7fffffffffffffff: return 9
106  return 10
107 
108 
109 def _TagSize(field_number):
110  """Returns the number of bytes required to serialize a tag with this field
111  number."""
112  # Just pass in type 0, since the type won't affect the tag+type size.
113  return _VarintSize(wire_format.PackTag(field_number, 0))
114 
115 
116 # --------------------------------------------------------------------
117 # In this section we define some generic sizers. Each of these functions
118 # takes parameters specific to a particular field type, e.g. int32 or fixed64.
119 # It returns another function which in turn takes parameters specific to a
120 # particular field, e.g. the field number and whether it is repeated or packed.
121 # Look at the next section to see how these are used.
122 
123 
124 def _SimpleSizer(compute_value_size):
125  """A sizer which uses the function compute_value_size to compute the size of
126  each value. Typically compute_value_size is _VarintSize."""
127 
128  def SpecificSizer(field_number, is_repeated, is_packed):
129  tag_size = _TagSize(field_number)
130  if is_packed:
131  local_VarintSize = _VarintSize
132  def PackedFieldSize(value):
133  result = 0
134  for element in value:
135  result += compute_value_size(element)
136  return result + local_VarintSize(result) + tag_size
137  return PackedFieldSize
138  elif is_repeated:
139  def RepeatedFieldSize(value):
140  result = tag_size * len(value)
141  for element in value:
142  result += compute_value_size(element)
143  return result
144  return RepeatedFieldSize
145  else:
146  def FieldSize(value):
147  return tag_size + compute_value_size(value)
148  return FieldSize
149 
150  return SpecificSizer
151 
152 
153 def _ModifiedSizer(compute_value_size, modify_value):
154  """Like SimpleSizer, but modify_value is invoked on each value before it is
155  passed to compute_value_size. modify_value is typically ZigZagEncode."""
156 
157  def SpecificSizer(field_number, is_repeated, is_packed):
158  tag_size = _TagSize(field_number)
159  if is_packed:
160  local_VarintSize = _VarintSize
161  def PackedFieldSize(value):
162  result = 0
163  for element in value:
164  result += compute_value_size(modify_value(element))
165  return result + local_VarintSize(result) + tag_size
166  return PackedFieldSize
167  elif is_repeated:
168  def RepeatedFieldSize(value):
169  result = tag_size * len(value)
170  for element in value:
171  result += compute_value_size(modify_value(element))
172  return result
173  return RepeatedFieldSize
174  else:
175  def FieldSize(value):
176  return tag_size + compute_value_size(modify_value(value))
177  return FieldSize
178 
179  return SpecificSizer
180 
181 
182 def _FixedSizer(value_size):
183  """Like _SimpleSizer except for a fixed-size field. The input is the size
184  of one value."""
185 
186  def SpecificSizer(field_number, is_repeated, is_packed):
187  tag_size = _TagSize(field_number)
188  if is_packed:
189  local_VarintSize = _VarintSize
190  def PackedFieldSize(value):
191  result = len(value) * value_size
192  return result + local_VarintSize(result) + tag_size
193  return PackedFieldSize
194  elif is_repeated:
195  element_size = value_size + tag_size
196  def RepeatedFieldSize(value):
197  return len(value) * element_size
198  return RepeatedFieldSize
199  else:
200  field_size = value_size + tag_size
201  def FieldSize(value):
202  return field_size
203  return FieldSize
204 
205  return SpecificSizer
206 
207 
208 # ====================================================================
209 # Here we declare a sizer constructor for each field type. Each "sizer
210 # constructor" is a function that takes (field_number, is_repeated, is_packed)
211 # as parameters and returns a sizer, which in turn takes a field value as
212 # a parameter and returns its encoded size.
213 
214 
215 Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize)
216 
217 UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize)
218 
219 SInt32Sizer = SInt64Sizer = _ModifiedSizer(
220  _SignedVarintSize, wire_format.ZigZagEncode)
221 
222 Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4)
223 Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8)
224 
225 BoolSizer = _FixedSizer(1)
226 
227 
228 def StringSizer(field_number, is_repeated, is_packed):
229  """Returns a sizer for a string field."""
230 
231  tag_size = _TagSize(field_number)
232  local_VarintSize = _VarintSize
233  local_len = len
234  assert not is_packed
235  if is_repeated:
236  def RepeatedFieldSize(value):
237  result = tag_size * len(value)
238  for element in value:
239  l = local_len(element.encode('utf-8'))
240  result += local_VarintSize(l) + l
241  return result
242  return RepeatedFieldSize
243  else:
244  def FieldSize(value):
245  l = local_len(value.encode('utf-8'))
246  return tag_size + local_VarintSize(l) + l
247  return FieldSize
248 
249 
250 def BytesSizer(field_number, is_repeated, is_packed):
251  """Returns a sizer for a bytes field."""
252 
253  tag_size = _TagSize(field_number)
254  local_VarintSize = _VarintSize
255  local_len = len
256  assert not is_packed
257  if is_repeated:
258  def RepeatedFieldSize(value):
259  result = tag_size * len(value)
260  for element in value:
261  l = local_len(element)
262  result += local_VarintSize(l) + l
263  return result
264  return RepeatedFieldSize
265  else:
266  def FieldSize(value):
267  l = local_len(value)
268  return tag_size + local_VarintSize(l) + l
269  return FieldSize
270 
271 
272 def GroupSizer(field_number, is_repeated, is_packed):
273  """Returns a sizer for a group field."""
274 
275  tag_size = _TagSize(field_number) * 2
276  assert not is_packed
277  if is_repeated:
278  def RepeatedFieldSize(value):
279  result = tag_size * len(value)
280  for element in value:
281  result += element.ByteSize()
282  return result
283  return RepeatedFieldSize
284  else:
285  def FieldSize(value):
286  return tag_size + value.ByteSize()
287  return FieldSize
288 
289 
290 def MessageSizer(field_number, is_repeated, is_packed):
291  """Returns a sizer for a message field."""
292 
293  tag_size = _TagSize(field_number)
294  local_VarintSize = _VarintSize
295  assert not is_packed
296  if is_repeated:
297  def RepeatedFieldSize(value):
298  result = tag_size * len(value)
299  for element in value:
300  l = element.ByteSize()
301  result += local_VarintSize(l) + l
302  return result
303  return RepeatedFieldSize
304  else:
305  def FieldSize(value):
306  l = value.ByteSize()
307  return tag_size + local_VarintSize(l) + l
308  return FieldSize
309 
310 
311 # --------------------------------------------------------------------
312 # MessageSet is special: it needs custom logic to compute its size properly.
313 
314 
315 def MessageSetItemSizer(field_number):
316  """Returns a sizer for extensions of MessageSet.
317 
318  The message set message looks like this:
319  message MessageSet {
320  repeated group Item = 1 {
321  required int32 type_id = 2;
322  required string message = 3;
323  }
324  }
325  """
326  static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) +
327  _TagSize(3))
328  local_VarintSize = _VarintSize
329 
330  def FieldSize(value):
331  l = value.ByteSize()
332  return static_size + local_VarintSize(l) + l
333 
334  return FieldSize
335 
336 
337 # --------------------------------------------------------------------
338 # Map is special: it needs custom logic to compute its size properly.
339 
340 
341 def MapSizer(field_descriptor, is_message_map):
342  """Returns a sizer for a map field."""
343 
344  # Can't look at field_descriptor.message_type._concrete_class because it may
345  # not have been initialized yet.
346  message_type = field_descriptor.message_type
347  message_sizer = MessageSizer(field_descriptor.number, False, False)
348 
349  def FieldSize(map_value):
350  total = 0
351  for key in map_value:
352  value = map_value[key]
353  # It's wasteful to create the messages and throw them away one second
354  # later since we'll do the same for the actual encode. But there's not an
355  # obvious way to avoid this within the current design without tons of code
356  # duplication. For message map, value.ByteSize() should be called to
357  # update the status.
358  entry_msg = message_type._concrete_class(key=key, value=value)
359  total += message_sizer(entry_msg)
360  if is_message_map:
361  value.ByteSize()
362  return total
363 
364  return FieldSize
365 
366 # ====================================================================
367 # Encoders!
368 
369 
370 def _VarintEncoder():
371  """Return an encoder for a basic varint value (does not include tag)."""
372 
373  local_int2byte = struct.Struct('>B').pack
374 
375  def EncodeVarint(write, value, unused_deterministic=None):
376  bits = value & 0x7f
377  value >>= 7
378  while value:
379  write(local_int2byte(0x80|bits))
380  bits = value & 0x7f
381  value >>= 7
382  return write(local_int2byte(bits))
383 
384  return EncodeVarint
385 
386 
388  """Return an encoder for a basic signed varint value (does not include
389  tag)."""
390 
391  local_int2byte = struct.Struct('>B').pack
392 
393  def EncodeSignedVarint(write, value, unused_deterministic=None):
394  if value < 0:
395  value += (1 << 64)
396  bits = value & 0x7f
397  value >>= 7
398  while value:
399  write(local_int2byte(0x80|bits))
400  bits = value & 0x7f
401  value >>= 7
402  return write(local_int2byte(bits))
403 
404  return EncodeSignedVarint
405 
406 
407 _EncodeVarint = _VarintEncoder()
408 _EncodeSignedVarint = _SignedVarintEncoder()
409 
410 
411 def _VarintBytes(value):
412  """Encode the given integer as a varint and return the bytes. This is only
413  called at startup time so it doesn't need to be fast."""
414 
415  pieces = []
416  _EncodeVarint(pieces.append, value, True)
417  return b"".join(pieces)
418 
419 
420 def TagBytes(field_number, wire_type):
421  """Encode the given tag and return the bytes. Only called at startup."""
422 
423  return bytes(_VarintBytes(wire_format.PackTag(field_number, wire_type)))
424 
425 # --------------------------------------------------------------------
426 # As with sizers (see above), we have a number of common encoder
427 # implementations.
428 
429 
430 def _SimpleEncoder(wire_type, encode_value, compute_value_size):
431  """Return a constructor for an encoder for fields of a particular type.
432 
433  Args:
434  wire_type: The field's wire type, for encoding tags.
435  encode_value: A function which encodes an individual value, e.g.
436  _EncodeVarint().
437  compute_value_size: A function which computes the size of an individual
438  value, e.g. _VarintSize().
439  """
440 
441  def SpecificEncoder(field_number, is_repeated, is_packed):
442  if is_packed:
443  tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
444  local_EncodeVarint = _EncodeVarint
445  def EncodePackedField(write, value, deterministic):
446  write(tag_bytes)
447  size = 0
448  for element in value:
449  size += compute_value_size(element)
450  local_EncodeVarint(write, size, deterministic)
451  for element in value:
452  encode_value(write, element, deterministic)
453  return EncodePackedField
454  elif is_repeated:
455  tag_bytes = TagBytes(field_number, wire_type)
456  def EncodeRepeatedField(write, value, deterministic):
457  for element in value:
458  write(tag_bytes)
459  encode_value(write, element, deterministic)
460  return EncodeRepeatedField
461  else:
462  tag_bytes = TagBytes(field_number, wire_type)
463  def EncodeField(write, value, deterministic):
464  write(tag_bytes)
465  return encode_value(write, value, deterministic)
466  return EncodeField
467 
468  return SpecificEncoder
469 
470 
471 def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value):
472  """Like SimpleEncoder but additionally invokes modify_value on every value
473  before passing it to encode_value. Usually modify_value is ZigZagEncode."""
474 
475  def SpecificEncoder(field_number, is_repeated, is_packed):
476  if is_packed:
477  tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
478  local_EncodeVarint = _EncodeVarint
479  def EncodePackedField(write, value, deterministic):
480  write(tag_bytes)
481  size = 0
482  for element in value:
483  size += compute_value_size(modify_value(element))
484  local_EncodeVarint(write, size, deterministic)
485  for element in value:
486  encode_value(write, modify_value(element), deterministic)
487  return EncodePackedField
488  elif is_repeated:
489  tag_bytes = TagBytes(field_number, wire_type)
490  def EncodeRepeatedField(write, value, deterministic):
491  for element in value:
492  write(tag_bytes)
493  encode_value(write, modify_value(element), deterministic)
494  return EncodeRepeatedField
495  else:
496  tag_bytes = TagBytes(field_number, wire_type)
497  def EncodeField(write, value, deterministic):
498  write(tag_bytes)
499  return encode_value(write, modify_value(value), deterministic)
500  return EncodeField
501 
502  return SpecificEncoder
503 
504 
505 def _StructPackEncoder(wire_type, format):
506  """Return a constructor for an encoder for a fixed-width field.
507 
508  Args:
509  wire_type: The field's wire type, for encoding tags.
510  format: The format string to pass to struct.pack().
511  """
512 
513  value_size = struct.calcsize(format)
514 
515  def SpecificEncoder(field_number, is_repeated, is_packed):
516  local_struct_pack = struct.pack
517  if is_packed:
518  tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
519  local_EncodeVarint = _EncodeVarint
520  def EncodePackedField(write, value, deterministic):
521  write(tag_bytes)
522  local_EncodeVarint(write, len(value) * value_size, deterministic)
523  for element in value:
524  write(local_struct_pack(format, element))
525  return EncodePackedField
526  elif is_repeated:
527  tag_bytes = TagBytes(field_number, wire_type)
528  def EncodeRepeatedField(write, value, unused_deterministic=None):
529  for element in value:
530  write(tag_bytes)
531  write(local_struct_pack(format, element))
532  return EncodeRepeatedField
533  else:
534  tag_bytes = TagBytes(field_number, wire_type)
535  def EncodeField(write, value, unused_deterministic=None):
536  write(tag_bytes)
537  return write(local_struct_pack(format, value))
538  return EncodeField
539 
540  return SpecificEncoder
541 
542 
543 def _FloatingPointEncoder(wire_type, format):
544  """Return a constructor for an encoder for float fields.
545 
546  This is like StructPackEncoder, but catches errors that may be due to
547  passing non-finite floating-point values to struct.pack, and makes a
548  second attempt to encode those values.
549 
550  Args:
551  wire_type: The field's wire type, for encoding tags.
552  format: The format string to pass to struct.pack().
553  """
554 
555  value_size = struct.calcsize(format)
556  if value_size == 4:
557  def EncodeNonFiniteOrRaise(write, value):
558  # Remember that the serialized form uses little-endian byte order.
559  if value == _POS_INF:
560  write(b'\x00\x00\x80\x7F')
561  elif value == _NEG_INF:
562  write(b'\x00\x00\x80\xFF')
563  elif value != value: # NaN
564  write(b'\x00\x00\xC0\x7F')
565  else:
566  raise
567  elif value_size == 8:
568  def EncodeNonFiniteOrRaise(write, value):
569  if value == _POS_INF:
570  write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F')
571  elif value == _NEG_INF:
572  write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF')
573  elif value != value: # NaN
574  write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
575  else:
576  raise
577  else:
578  raise ValueError('Can\'t encode floating-point values that are '
579  '%d bytes long (only 4 or 8)' % value_size)
580 
581  def SpecificEncoder(field_number, is_repeated, is_packed):
582  local_struct_pack = struct.pack
583  if is_packed:
584  tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
585  local_EncodeVarint = _EncodeVarint
586  def EncodePackedField(write, value, deterministic):
587  write(tag_bytes)
588  local_EncodeVarint(write, len(value) * value_size, deterministic)
589  for element in value:
590  # This try/except block is going to be faster than any code that
591  # we could write to check whether element is finite.
592  try:
593  write(local_struct_pack(format, element))
594  except SystemError:
595  EncodeNonFiniteOrRaise(write, element)
596  return EncodePackedField
597  elif is_repeated:
598  tag_bytes = TagBytes(field_number, wire_type)
599  def EncodeRepeatedField(write, value, unused_deterministic=None):
600  for element in value:
601  write(tag_bytes)
602  try:
603  write(local_struct_pack(format, element))
604  except SystemError:
605  EncodeNonFiniteOrRaise(write, element)
606  return EncodeRepeatedField
607  else:
608  tag_bytes = TagBytes(field_number, wire_type)
609  def EncodeField(write, value, unused_deterministic=None):
610  write(tag_bytes)
611  try:
612  write(local_struct_pack(format, value))
613  except SystemError:
614  EncodeNonFiniteOrRaise(write, value)
615  return EncodeField
616 
617  return SpecificEncoder
618 
619 
620 # ====================================================================
621 # Here we declare an encoder constructor for each field type. These work
622 # very similarly to sizer constructors, described earlier.
623 
624 
625 Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder(
626  wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize)
627 
628 UInt32Encoder = UInt64Encoder = _SimpleEncoder(
629  wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize)
630 
631 SInt32Encoder = SInt64Encoder = _ModifiedEncoder(
632  wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize,
633  wire_format.ZigZagEncode)
634 
635 # Note that Python conveniently guarantees that when using the '<' prefix on
636 # formats, they will also have the same size across all platforms (as opposed
637 # to without the prefix, where their sizes depend on the C compiler's basic
638 # type sizes).
639 Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I')
640 Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q')
641 SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i')
642 SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q')
643 FloatEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED32, '<f')
644 DoubleEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d')
645 
646 
647 def BoolEncoder(field_number, is_repeated, is_packed):
648  """Returns an encoder for a boolean field."""
649 
650  false_byte = b'\x00'
651  true_byte = b'\x01'
652  if is_packed:
653  tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
654  local_EncodeVarint = _EncodeVarint
655  def EncodePackedField(write, value, deterministic):
656  write(tag_bytes)
657  local_EncodeVarint(write, len(value), deterministic)
658  for element in value:
659  if element:
660  write(true_byte)
661  else:
662  write(false_byte)
663  return EncodePackedField
664  elif is_repeated:
665  tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
666  def EncodeRepeatedField(write, value, unused_deterministic=None):
667  for element in value:
668  write(tag_bytes)
669  if element:
670  write(true_byte)
671  else:
672  write(false_byte)
673  return EncodeRepeatedField
674  else:
675  tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
676  def EncodeField(write, value, unused_deterministic=None):
677  write(tag_bytes)
678  if value:
679  return write(true_byte)
680  return write(false_byte)
681  return EncodeField
682 
683 
684 def StringEncoder(field_number, is_repeated, is_packed):
685  """Returns an encoder for a string field."""
686 
687  tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
688  local_EncodeVarint = _EncodeVarint
689  local_len = len
690  assert not is_packed
691  if is_repeated:
692  def EncodeRepeatedField(write, value, deterministic):
693  for element in value:
694  encoded = element.encode('utf-8')
695  write(tag)
696  local_EncodeVarint(write, local_len(encoded), deterministic)
697  write(encoded)
698  return EncodeRepeatedField
699  else:
700  def EncodeField(write, value, deterministic):
701  encoded = value.encode('utf-8')
702  write(tag)
703  local_EncodeVarint(write, local_len(encoded), deterministic)
704  return write(encoded)
705  return EncodeField
706 
707 
708 def BytesEncoder(field_number, is_repeated, is_packed):
709  """Returns an encoder for a bytes field."""
710 
711  tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
712  local_EncodeVarint = _EncodeVarint
713  local_len = len
714  assert not is_packed
715  if is_repeated:
716  def EncodeRepeatedField(write, value, deterministic):
717  for element in value:
718  write(tag)
719  local_EncodeVarint(write, local_len(element), deterministic)
720  write(element)
721  return EncodeRepeatedField
722  else:
723  def EncodeField(write, value, deterministic):
724  write(tag)
725  local_EncodeVarint(write, local_len(value), deterministic)
726  return write(value)
727  return EncodeField
728 
729 
730 def GroupEncoder(field_number, is_repeated, is_packed):
731  """Returns an encoder for a group field."""
732 
733  start_tag = TagBytes(field_number, wire_format.WIRETYPE_START_GROUP)
734  end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP)
735  assert not is_packed
736  if is_repeated:
737  def EncodeRepeatedField(write, value, deterministic):
738  for element in value:
739  write(start_tag)
740  element._InternalSerialize(write, deterministic)
741  write(end_tag)
742  return EncodeRepeatedField
743  else:
744  def EncodeField(write, value, deterministic):
745  write(start_tag)
746  value._InternalSerialize(write, deterministic)
747  return write(end_tag)
748  return EncodeField
749 
750 
751 def MessageEncoder(field_number, is_repeated, is_packed):
752  """Returns an encoder for a message field."""
753 
754  tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
755  local_EncodeVarint = _EncodeVarint
756  assert not is_packed
757  if is_repeated:
758  def EncodeRepeatedField(write, value, deterministic):
759  for element in value:
760  write(tag)
761  local_EncodeVarint(write, element.ByteSize(), deterministic)
762  element._InternalSerialize(write, deterministic)
763  return EncodeRepeatedField
764  else:
765  def EncodeField(write, value, deterministic):
766  write(tag)
767  local_EncodeVarint(write, value.ByteSize(), deterministic)
768  return value._InternalSerialize(write, deterministic)
769  return EncodeField
770 
771 
772 # --------------------------------------------------------------------
773 # As before, MessageSet is special.
774 
775 
776 def MessageSetItemEncoder(field_number):
777  """Encoder for extensions of MessageSet.
778 
779  The message set message looks like this:
780  message MessageSet {
781  repeated group Item = 1 {
782  required int32 type_id = 2;
783  required string message = 3;
784  }
785  }
786  """
787  start_bytes = b"".join([
788  TagBytes(1, wire_format.WIRETYPE_START_GROUP),
789  TagBytes(2, wire_format.WIRETYPE_VARINT),
790  _VarintBytes(field_number),
791  TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)])
792  end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP)
793  local_EncodeVarint = _EncodeVarint
794 
795  def EncodeField(write, value, deterministic):
796  write(start_bytes)
797  local_EncodeVarint(write, value.ByteSize(), deterministic)
798  value._InternalSerialize(write, deterministic)
799  return write(end_bytes)
800 
801  return EncodeField
802 
803 
804 # --------------------------------------------------------------------
805 # As before, Map is special.
806 
807 
808 def MapEncoder(field_descriptor):
809  """Encoder for extensions of MessageSet.
810 
811  Maps always have a wire format like this:
812  message MapEntry {
813  key_type key = 1;
814  value_type value = 2;
815  }
816  repeated MapEntry map = N;
817  """
818  # Can't look at field_descriptor.message_type._concrete_class because it may
819  # not have been initialized yet.
820  message_type = field_descriptor.message_type
821  encode_message = MessageEncoder(field_descriptor.number, False, False)
822 
823  def EncodeField(write, value, deterministic):
824  value_keys = sorted(value.keys()) if deterministic else value
825  for key in value_keys:
826  entry_msg = message_type._concrete_class(key=key, value=value[key])
827  encode_message(write, entry_msg, deterministic)
828 
829  return EncodeField
google::protobuf.internal.encoder._TagSize
def _TagSize(field_number)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:111
google::protobuf.internal.encoder._SimpleEncoder
def _SimpleEncoder(wire_type, encode_value, compute_value_size)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:429
write
#define write
Definition: test-fs.c:47
google::protobuf.internal.encoder._VarintBytes
def _VarintBytes(value)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:409
google::protobuf.internal.encoder._FloatingPointEncoder
def _FloatingPointEncoder(wire_type, format)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:542
google::protobuf.internal.encoder._SignedVarintEncoder
def _SignedVarintEncoder()
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:387
google::protobuf.internal.encoder._SignedVarintSize
def _SignedVarintSize(value)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:96
google::protobuf.internal.encoder.MessageEncoder
def MessageEncoder(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:750
google::protobuf.internal.encoder.MapEncoder
def MapEncoder(field_descriptor)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:807
google::protobuf.internal.encoder.StringEncoder
def StringEncoder(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:683
google::protobuf.internal
Definition: third_party/bloaty/third_party/protobuf/python/google/protobuf/internal/__init__.py:1
google::protobuf.internal.encoder.MapSizer
def MapSizer(field_descriptor, is_message_map)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:343
google::protobuf.internal.encoder.MessageSetItemEncoder
def MessageSetItemEncoder(field_number)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:775
EncodeVarint
void EncodeVarint(uint64_t val, std::string *str)
Definition: upb/upb/util/compare_test.cc:107
google::protobuf.internal.encoder._SimpleSizer
def _SimpleSizer(compute_value_size)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:126
google::protobuf.internal.encoder.GroupEncoder
def GroupEncoder(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:729
google::protobuf.internal.encoder._ModifiedSizer
def _ModifiedSizer(compute_value_size, modify_value)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:155
google::protobuf.internal.encoder._VarintEncoder
def _VarintEncoder()
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:372
google::protobuf.internal.encoder.BytesEncoder
def BytesEncoder(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:707
google::protobuf.internal.encoder._VarintSize
def _VarintSize(value)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:82
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
google::protobuf.internal.encoder._EncodeVarint
def _EncodeVarint
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:405
google::protobuf.internal.encoder.StringSizer
def StringSizer(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:230
encode_message
static void encode_message(upb_encstate *e, const upb_msg *msg, const upb_msglayout *m, size_t *size)
Definition: php-upb.c:1412
google::protobuf.internal.encoder._ModifiedEncoder
def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:470
google::protobuf.internal.encoder.TagBytes
def TagBytes(field_number, wire_type)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:418
google::protobuf.internal.encoder.MessageSetItemSizer
def MessageSetItemSizer(field_number)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:317
google::protobuf.internal.encoder.BytesSizer
def BytesSizer(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:252
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
google::protobuf.internal.encoder._FixedSizer
def _FixedSizer(value_size)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:184
google::protobuf.internal.encoder.MessageSizer
def MessageSizer(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:292
google::protobuf.internal.encoder._StructPackEncoder
def _StructPackEncoder(wire_type, format)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:504
google::protobuf.internal.encoder.GroupSizer
def GroupSizer(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:274
google::protobuf.internal.encoder.BoolEncoder
def BoolEncoder(field_number, is_repeated, is_packed)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/encoder.py:646


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:18