encoder.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. # Protocol Buffers - Google's data interchange format
  2. # Copyright 2008 Google Inc. All rights reserved.
  3. #
  4. # Use of this source code is governed by a BSD-style
  5. # license that can be found in the LICENSE file or at
  6. # https://developers.google.com/open-source/licenses/bsd
  7. """Code for encoding protocol message primitives.
  8. Contains the logic for encoding every logical protocol field type
  9. into one of the 5 physical wire types.
  10. This code is designed to push the Python interpreter's performance to the
  11. limits.
  12. The basic idea is that at startup time, for every field (i.e. every
  13. FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The
  14. sizer takes a value of this field's type and computes its byte size. The
  15. encoder takes a writer function and a value. It encodes the value into byte
  16. strings and invokes the writer function to write those strings. Typically the
  17. writer function is the write() method of a BytesIO.
  18. We try to do as much work as possible when constructing the writer and the
  19. sizer rather than when calling them. In particular:
  20. * We copy any needed global functions to local variables, so that we do not need
  21. to do costly global table lookups at runtime.
  22. * Similarly, we try to do any attribute lookups at startup time if possible.
  23. * Every field's tag is encoded to bytes at startup, since it can't change at
  24. runtime.
  25. * Whatever component of the field size we can compute at startup, we do.
  26. * We *avoid* sharing code if doing so would make the code slower and not sharing
  27. does not burden us too much. For example, encoders for repeated fields do
  28. not just call the encoders for singular fields in a loop because this would
  29. add an extra function call overhead for every loop iteration; instead, we
  30. manually inline the single-value encoder into the loop.
  31. * If a Python function lacks a return statement, Python actually generates
  32. instructions to pop the result of the last statement off the stack, push
  33. None onto the stack, and then return that. If we really don't care what
  34. value is returned, then we can save two instructions by returning the
  35. result of the last statement. It looks funny but it helps.
  36. * We assume that type and bounds checking has happened at a higher level.
  37. """
  38. __author__ = 'kenton@google.com (Kenton Varda)'
  39. import struct
  40. from google.protobuf.internal import wire_format
  41. # This will overflow and thus become IEEE-754 "infinity". We would use
  42. # "float('inf')" but it doesn't work on Windows pre-Python-2.6.
  43. _POS_INF = 1e10000
  44. _NEG_INF = -_POS_INF
  45. def _VarintSize(value):
  46. """Compute the size of a varint value."""
  47. if value <= 0x7F:
  48. return 1
  49. if value <= 0x3FFF:
  50. return 2
  51. if value <= 0x1FFFFF:
  52. return 3
  53. if value <= 0xFFFFFFF:
  54. return 4
  55. if value <= 0x7FFFFFFFF:
  56. return 5
  57. if value <= 0x3FFFFFFFFFF:
  58. return 6
  59. if value <= 0x1FFFFFFFFFFFF:
  60. return 7
  61. if value <= 0xFFFFFFFFFFFFFF:
  62. return 8
  63. if value <= 0x7FFFFFFFFFFFFFFF:
  64. return 9
  65. return 10
  66. def _SignedVarintSize(value):
  67. """Compute the size of a signed varint value."""
  68. if value < 0:
  69. return 10
  70. if value <= 0x7F:
  71. return 1
  72. if value <= 0x3FFF:
  73. return 2
  74. if value <= 0x1FFFFF:
  75. return 3
  76. if value <= 0xFFFFFFF:
  77. return 4
  78. if value <= 0x7FFFFFFFF:
  79. return 5
  80. if value <= 0x3FFFFFFFFFF:
  81. return 6
  82. if value <= 0x1FFFFFFFFFFFF:
  83. return 7
  84. if value <= 0xFFFFFFFFFFFFFF:
  85. return 8
  86. if value <= 0x7FFFFFFFFFFFFFFF:
  87. return 9
  88. return 10
  89. def _TagSize(field_number):
  90. """Returns the number of bytes required to serialize a tag with this field
  91. number.
  92. """
  93. # Just pass in type 0, since the type won't affect the tag+type size.
  94. return _VarintSize(wire_format.PackTag(field_number, 0))
  95. # --------------------------------------------------------------------
  96. # In this section we define some generic sizers. Each of these functions
  97. # takes parameters specific to a particular field type, e.g. int32 or fixed64.
  98. # It returns another function which in turn takes parameters specific to a
  99. # particular field, e.g. the field number and whether it is repeated or packed.
  100. # Look at the next section to see how these are used.
  101. def _SimpleSizer(compute_value_size):
  102. """A sizer which uses the function compute_value_size to compute the size of
  103. each value. Typically compute_value_size is _VarintSize.
  104. """
  105. def SpecificSizer(field_number, is_repeated, is_packed):
  106. tag_size = _TagSize(field_number)
  107. if is_packed:
  108. local_VarintSize = _VarintSize
  109. def PackedFieldSize(value):
  110. result = 0
  111. for element in value:
  112. result += compute_value_size(element)
  113. return result + local_VarintSize(result) + tag_size
  114. return PackedFieldSize
  115. elif is_repeated:
  116. def RepeatedFieldSize(value):
  117. result = tag_size * len(value)
  118. for element in value:
  119. result += compute_value_size(element)
  120. return result
  121. return RepeatedFieldSize
  122. else:
  123. def FieldSize(value):
  124. return tag_size + compute_value_size(value)
  125. return FieldSize
  126. return SpecificSizer
  127. def _ModifiedSizer(compute_value_size, modify_value):
  128. """Like SimpleSizer, but modify_value is invoked on each value before it is
  129. passed to compute_value_size. modify_value is typically ZigZagEncode.
  130. """
  131. def SpecificSizer(field_number, is_repeated, is_packed):
  132. tag_size = _TagSize(field_number)
  133. if is_packed:
  134. local_VarintSize = _VarintSize
  135. def PackedFieldSize(value):
  136. result = 0
  137. for element in value:
  138. result += compute_value_size(modify_value(element))
  139. return result + local_VarintSize(result) + tag_size
  140. return PackedFieldSize
  141. elif is_repeated:
  142. def RepeatedFieldSize(value):
  143. result = tag_size * len(value)
  144. for element in value:
  145. result += compute_value_size(modify_value(element))
  146. return result
  147. return RepeatedFieldSize
  148. else:
  149. def FieldSize(value):
  150. return tag_size + compute_value_size(modify_value(value))
  151. return FieldSize
  152. return SpecificSizer
  153. def _FixedSizer(value_size):
  154. """Like _SimpleSizer except for a fixed-size field.
  155. The input is the size of one value.
  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 = len(value) * value_size
  163. return result + local_VarintSize(result) + tag_size
  164. return PackedFieldSize
  165. elif is_repeated:
  166. element_size = value_size + tag_size
  167. def RepeatedFieldSize(value):
  168. return len(value) * element_size
  169. return RepeatedFieldSize
  170. else:
  171. field_size = value_size + tag_size
  172. def FieldSize(value):
  173. return field_size
  174. return FieldSize
  175. return SpecificSizer
  176. # ====================================================================
  177. # Here we declare a sizer constructor for each field type. Each "sizer
  178. # constructor" is a function that takes (field_number, is_repeated, is_packed)
  179. # as parameters and returns a sizer, which in turn takes a field value as
  180. # a parameter and returns its encoded size.
  181. Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize)
  182. UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize)
  183. SInt32Sizer = SInt64Sizer = _ModifiedSizer(
  184. _SignedVarintSize, wire_format.ZigZagEncode
  185. )
  186. Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4)
  187. Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8)
  188. BoolSizer = _FixedSizer(1)
  189. def StringSizer(field_number, is_repeated, is_packed):
  190. """Returns a sizer for a string field."""
  191. tag_size = _TagSize(field_number)
  192. local_VarintSize = _VarintSize
  193. local_len = len
  194. assert not is_packed
  195. if is_repeated:
  196. def RepeatedFieldSize(value):
  197. result = tag_size * len(value)
  198. for element in value:
  199. l = local_len(element.encode('utf-8'))
  200. result += local_VarintSize(l) + l
  201. return result
  202. return RepeatedFieldSize
  203. else:
  204. def FieldSize(value):
  205. l = local_len(value.encode('utf-8'))
  206. return tag_size + local_VarintSize(l) + l
  207. return FieldSize
  208. def BytesSizer(field_number, is_repeated, is_packed):
  209. """Returns a sizer for a bytes field."""
  210. tag_size = _TagSize(field_number)
  211. local_VarintSize = _VarintSize
  212. local_len = len
  213. assert not is_packed
  214. if is_repeated:
  215. def RepeatedFieldSize(value):
  216. result = tag_size * len(value)
  217. for element in value:
  218. l = local_len(element)
  219. result += local_VarintSize(l) + l
  220. return result
  221. return RepeatedFieldSize
  222. else:
  223. def FieldSize(value):
  224. l = local_len(value)
  225. return tag_size + local_VarintSize(l) + l
  226. return FieldSize
  227. def GroupSizer(field_number, is_repeated, is_packed):
  228. """Returns a sizer for a group field."""
  229. tag_size = _TagSize(field_number) * 2
  230. assert not is_packed
  231. if is_repeated:
  232. def RepeatedFieldSize(value):
  233. result = tag_size * len(value)
  234. for element in value:
  235. result += element.ByteSize()
  236. return result
  237. return RepeatedFieldSize
  238. else:
  239. def FieldSize(value):
  240. return tag_size + value.ByteSize()
  241. return FieldSize
  242. def MessageSizer(field_number, is_repeated, is_packed):
  243. """Returns a sizer for a message field."""
  244. tag_size = _TagSize(field_number)
  245. local_VarintSize = _VarintSize
  246. assert not is_packed
  247. if is_repeated:
  248. def RepeatedFieldSize(value):
  249. result = tag_size * len(value)
  250. for element in value:
  251. l = element.ByteSize()
  252. result += local_VarintSize(l) + l
  253. return result
  254. return RepeatedFieldSize
  255. else:
  256. def FieldSize(value):
  257. l = value.ByteSize()
  258. return tag_size + local_VarintSize(l) + l
  259. return FieldSize
  260. # --------------------------------------------------------------------
  261. # MessageSet is special: it needs custom logic to compute its size properly.
  262. def MessageSetItemSizer(field_number):
  263. """Returns a sizer for extensions of MessageSet.
  264. The message set message looks like this:
  265. message MessageSet {
  266. repeated group Item = 1 {
  267. required int32 type_id = 2;
  268. required string message = 3;
  269. }
  270. }
  271. """
  272. static_size = (
  273. _TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) + _TagSize(3)
  274. )
  275. local_VarintSize = _VarintSize
  276. def FieldSize(value):
  277. l = value.ByteSize()
  278. return static_size + local_VarintSize(l) + l
  279. return FieldSize
  280. # --------------------------------------------------------------------
  281. # Map is special: it needs custom logic to compute its size properly.
  282. def MapSizer(field_descriptor, key_sizer, value_sizer):
  283. """Returns a sizer for a map field."""
  284. def FieldSize(map_value):
  285. tag_size = _TagSize(field_descriptor.number)
  286. local_VarintSize = _VarintSize
  287. total = 0
  288. for key in map_value:
  289. val = map_value[key]
  290. entry_size = key_sizer(key) + value_sizer(val)
  291. total += tag_size + local_VarintSize(entry_size) + entry_size
  292. return total
  293. return FieldSize
  294. # ====================================================================
  295. # Encoders!
  296. def _VarintEncoder():
  297. """Return an encoder for a basic varint value (does not include tag)."""
  298. local_int2byte = struct.Struct('>B').pack
  299. def EncodeVarint(write, value, unused_deterministic=None):
  300. bits = value & 0x7F
  301. value >>= 7
  302. while value:
  303. write(local_int2byte(0x80 | bits))
  304. bits = value & 0x7F
  305. value >>= 7
  306. return write(local_int2byte(bits))
  307. return EncodeVarint
  308. def _SignedVarintEncoder():
  309. """Return an encoder for a basic signed varint value (does not include
  310. tag).
  311. """
  312. local_int2byte = struct.Struct('>B').pack
  313. def EncodeSignedVarint(write, value, unused_deterministic=None):
  314. if value < 0:
  315. value += 1 << 64
  316. bits = value & 0x7F
  317. value >>= 7
  318. while value:
  319. write(local_int2byte(0x80 | bits))
  320. bits = value & 0x7F
  321. value >>= 7
  322. return write(local_int2byte(bits))
  323. return EncodeSignedVarint
  324. _EncodeVarint = _VarintEncoder()
  325. _EncodeSignedVarint = _SignedVarintEncoder()
  326. def _VarintBytes(value):
  327. """Encode the given integer as a varint and return the bytes.
  328. This is only called at startup time so it doesn't need to be fast.
  329. """
  330. pieces = []
  331. _EncodeVarint(pieces.append, value, True)
  332. return b''.join(pieces)
  333. def TagBytes(field_number, wire_type):
  334. """Encode the given tag and return the bytes. Only called at startup."""
  335. return bytes(_VarintBytes(wire_format.PackTag(field_number, wire_type)))
  336. # --------------------------------------------------------------------
  337. # As with sizers (see above), we have a number of common encoder
  338. # implementations.
  339. def _SimpleEncoder(wire_type, encode_value, compute_value_size):
  340. """Return a constructor for an encoder for fields of a particular type.
  341. Args:
  342. wire_type: The field's wire type, for encoding tags.
  343. encode_value: A function which encodes an individual value, e.g.
  344. _EncodeVarint().
  345. compute_value_size: A function which computes the size of an individual
  346. value, e.g. _VarintSize().
  347. """
  348. def SpecificEncoder(field_number, is_repeated, is_packed):
  349. if is_packed:
  350. tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  351. local_EncodeVarint = _EncodeVarint
  352. def EncodePackedField(write, value, deterministic):
  353. write(tag_bytes)
  354. size = 0
  355. for element in value:
  356. size += compute_value_size(element)
  357. local_EncodeVarint(write, size, deterministic)
  358. for element in value:
  359. encode_value(write, element, deterministic)
  360. return EncodePackedField
  361. elif is_repeated:
  362. tag_bytes = TagBytes(field_number, wire_type)
  363. def EncodeRepeatedField(write, value, deterministic):
  364. for element in value:
  365. write(tag_bytes)
  366. encode_value(write, element, deterministic)
  367. return EncodeRepeatedField
  368. else:
  369. tag_bytes = TagBytes(field_number, wire_type)
  370. def EncodeField(write, value, deterministic):
  371. write(tag_bytes)
  372. return encode_value(write, value, deterministic)
  373. return EncodeField
  374. return SpecificEncoder
  375. def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value):
  376. """Like SimpleEncoder but additionally invokes modify_value on every value
  377. before passing it to encode_value. Usually modify_value is ZigZagEncode.
  378. """
  379. def SpecificEncoder(field_number, is_repeated, is_packed):
  380. if is_packed:
  381. tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  382. local_EncodeVarint = _EncodeVarint
  383. def EncodePackedField(write, value, deterministic):
  384. write(tag_bytes)
  385. size = 0
  386. for element in value:
  387. size += compute_value_size(modify_value(element))
  388. local_EncodeVarint(write, size, deterministic)
  389. for element in value:
  390. encode_value(write, modify_value(element), deterministic)
  391. return EncodePackedField
  392. elif is_repeated:
  393. tag_bytes = TagBytes(field_number, wire_type)
  394. def EncodeRepeatedField(write, value, deterministic):
  395. for element in value:
  396. write(tag_bytes)
  397. encode_value(write, modify_value(element), deterministic)
  398. return EncodeRepeatedField
  399. else:
  400. tag_bytes = TagBytes(field_number, wire_type)
  401. def EncodeField(write, value, deterministic):
  402. write(tag_bytes)
  403. return encode_value(write, modify_value(value), deterministic)
  404. return EncodeField
  405. return SpecificEncoder
  406. def _StructPackEncoder(wire_type, format):
  407. """Return a constructor for an encoder for a fixed-width field.
  408. Args:
  409. wire_type: The field's wire type, for encoding tags.
  410. format: The format string to pass to struct.pack().
  411. """
  412. value_size = struct.calcsize(format)
  413. def SpecificEncoder(field_number, is_repeated, is_packed):
  414. local_struct_pack = struct.pack
  415. if is_packed:
  416. tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  417. local_EncodeVarint = _EncodeVarint
  418. def EncodePackedField(write, value, deterministic):
  419. write(tag_bytes)
  420. local_EncodeVarint(write, len(value) * value_size, deterministic)
  421. for element in value:
  422. write(local_struct_pack(format, element))
  423. return EncodePackedField
  424. elif is_repeated:
  425. tag_bytes = TagBytes(field_number, wire_type)
  426. def EncodeRepeatedField(write, value, unused_deterministic=None):
  427. for element in value:
  428. write(tag_bytes)
  429. write(local_struct_pack(format, element))
  430. return EncodeRepeatedField
  431. else:
  432. tag_bytes = TagBytes(field_number, wire_type)
  433. def EncodeField(write, value, unused_deterministic=None):
  434. write(tag_bytes)
  435. return write(local_struct_pack(format, value))
  436. return EncodeField
  437. return SpecificEncoder
  438. def _FloatingPointEncoder(wire_type, format):
  439. """Return a constructor for an encoder for float fields.
  440. This is like StructPackEncoder, but catches errors that may be due to
  441. passing non-finite floating-point values to struct.pack, and makes a
  442. second attempt to encode those values.
  443. Args:
  444. wire_type: The field's wire type, for encoding tags.
  445. format: The format string to pass to struct.pack().
  446. """
  447. value_size = struct.calcsize(format)
  448. if value_size == 4:
  449. def EncodeNonFiniteOrRaise(write, value):
  450. # Remember that the serialized form uses little-endian byte order.
  451. if value == _POS_INF:
  452. write(b'\x00\x00\x80\x7F')
  453. elif value == _NEG_INF:
  454. write(b'\x00\x00\x80\xFF')
  455. elif value != value: # NaN
  456. write(b'\x00\x00\xC0\x7F')
  457. else:
  458. raise
  459. elif value_size == 8:
  460. def EncodeNonFiniteOrRaise(write, value):
  461. if value == _POS_INF:
  462. write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F')
  463. elif value == _NEG_INF:
  464. write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF')
  465. elif value != value: # NaN
  466. write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
  467. else:
  468. raise
  469. else:
  470. raise ValueError(
  471. "Can't encode floating-point values that are "
  472. '%d bytes long (only 4 or 8)' % value_size
  473. )
  474. def SpecificEncoder(field_number, is_repeated, is_packed):
  475. local_struct_pack = struct.pack
  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. local_EncodeVarint(write, len(value) * value_size, deterministic)
  482. for element in value:
  483. # This try/except block is going to be faster than any code that
  484. # we could write to check whether element is finite.
  485. try:
  486. write(local_struct_pack(format, element))
  487. except SystemError:
  488. EncodeNonFiniteOrRaise(write, element)
  489. return EncodePackedField
  490. elif is_repeated:
  491. tag_bytes = TagBytes(field_number, wire_type)
  492. def EncodeRepeatedField(write, value, unused_deterministic=None):
  493. for element in value:
  494. write(tag_bytes)
  495. try:
  496. write(local_struct_pack(format, element))
  497. except SystemError:
  498. EncodeNonFiniteOrRaise(write, element)
  499. return EncodeRepeatedField
  500. else:
  501. tag_bytes = TagBytes(field_number, wire_type)
  502. def EncodeField(write, value, unused_deterministic=None):
  503. write(tag_bytes)
  504. try:
  505. write(local_struct_pack(format, value))
  506. except SystemError:
  507. EncodeNonFiniteOrRaise(write, value)
  508. return EncodeField
  509. return SpecificEncoder
  510. # ====================================================================
  511. # Here we declare an encoder constructor for each field type. These work
  512. # very similarly to sizer constructors, described earlier.
  513. Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder(
  514. wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize
  515. )
  516. UInt32Encoder = UInt64Encoder = _SimpleEncoder(
  517. wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize
  518. )
  519. SInt32Encoder = SInt64Encoder = _ModifiedEncoder(
  520. wire_format.WIRETYPE_VARINT,
  521. _EncodeVarint,
  522. _VarintSize,
  523. wire_format.ZigZagEncode,
  524. )
  525. # Note that Python conveniently guarantees that when using the '<' prefix on
  526. # formats, they will also have the same size across all platforms (as opposed
  527. # to without the prefix, where their sizes depend on the C compiler's basic
  528. # type sizes).
  529. Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I')
  530. Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q')
  531. SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i')
  532. SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q')
  533. FloatEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED32, '<f')
  534. DoubleEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d')
  535. def BoolEncoder(field_number, is_repeated, is_packed):
  536. """Returns an encoder for a boolean field."""
  537. false_byte = b'\x00'
  538. true_byte = b'\x01'
  539. if is_packed:
  540. tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  541. local_EncodeVarint = _EncodeVarint
  542. def EncodePackedField(write, value, deterministic):
  543. write(tag_bytes)
  544. local_EncodeVarint(write, len(value), deterministic)
  545. for element in value:
  546. if element:
  547. write(true_byte)
  548. else:
  549. write(false_byte)
  550. return EncodePackedField
  551. elif is_repeated:
  552. tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
  553. def EncodeRepeatedField(write, value, unused_deterministic=None):
  554. for element in value:
  555. write(tag_bytes)
  556. if element:
  557. write(true_byte)
  558. else:
  559. write(false_byte)
  560. return EncodeRepeatedField
  561. else:
  562. tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
  563. def EncodeField(write, value, unused_deterministic=None):
  564. write(tag_bytes)
  565. if value:
  566. return write(true_byte)
  567. return write(false_byte)
  568. return EncodeField
  569. def StringEncoder(field_number, is_repeated, is_packed):
  570. """Returns an encoder for a string field."""
  571. tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  572. local_EncodeVarint = _EncodeVarint
  573. local_len = len
  574. assert not is_packed
  575. if is_repeated:
  576. def EncodeRepeatedField(write, value, deterministic):
  577. for element in value:
  578. encoded = element.encode('utf-8')
  579. write(tag)
  580. local_EncodeVarint(write, local_len(encoded), deterministic)
  581. write(encoded)
  582. return EncodeRepeatedField
  583. else:
  584. def EncodeField(write, value, deterministic):
  585. encoded = value.encode('utf-8')
  586. write(tag)
  587. local_EncodeVarint(write, local_len(encoded), deterministic)
  588. return write(encoded)
  589. return EncodeField
  590. def BytesEncoder(field_number, is_repeated, is_packed):
  591. """Returns an encoder for a bytes field."""
  592. tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  593. local_EncodeVarint = _EncodeVarint
  594. local_len = len
  595. assert not is_packed
  596. if is_repeated:
  597. def EncodeRepeatedField(write, value, deterministic):
  598. for element in value:
  599. write(tag)
  600. local_EncodeVarint(write, local_len(element), deterministic)
  601. write(element)
  602. return EncodeRepeatedField
  603. else:
  604. def EncodeField(write, value, deterministic):
  605. write(tag)
  606. local_EncodeVarint(write, local_len(value), deterministic)
  607. return write(value)
  608. return EncodeField
  609. def GroupEncoder(field_number, is_repeated, is_packed):
  610. """Returns an encoder for a group field."""
  611. start_tag = TagBytes(field_number, wire_format.WIRETYPE_START_GROUP)
  612. end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP)
  613. assert not is_packed
  614. if is_repeated:
  615. def EncodeRepeatedField(write, value, deterministic):
  616. for element in value:
  617. write(start_tag)
  618. element._InternalSerialize(write, deterministic)
  619. write(end_tag)
  620. return EncodeRepeatedField
  621. else:
  622. def EncodeField(write, value, deterministic):
  623. write(start_tag)
  624. value._InternalSerialize(write, deterministic)
  625. return write(end_tag)
  626. return EncodeField
  627. def MessageEncoder(field_number, is_repeated, is_packed):
  628. """Returns an encoder for a message field."""
  629. tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
  630. local_EncodeVarint = _EncodeVarint
  631. assert not is_packed
  632. if is_repeated:
  633. def EncodeRepeatedField(write, value, deterministic):
  634. for element in value:
  635. write(tag)
  636. local_EncodeVarint(write, element.ByteSize(), deterministic)
  637. element._InternalSerialize(write, deterministic)
  638. return EncodeRepeatedField
  639. else:
  640. def EncodeField(write, value, deterministic):
  641. write(tag)
  642. local_EncodeVarint(write, value.ByteSize(), deterministic)
  643. return value._InternalSerialize(write, deterministic)
  644. return EncodeField
  645. # --------------------------------------------------------------------
  646. # As before, MessageSet is special.
  647. def MessageSetItemEncoder(field_number):
  648. """Encoder for extensions of MessageSet.
  649. The message set message looks like this:
  650. message MessageSet {
  651. repeated group Item = 1 {
  652. required int32 type_id = 2;
  653. required string message = 3;
  654. }
  655. }
  656. """
  657. start_bytes = b''.join([
  658. TagBytes(1, wire_format.WIRETYPE_START_GROUP),
  659. TagBytes(2, wire_format.WIRETYPE_VARINT),
  660. _VarintBytes(field_number),
  661. TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED),
  662. ])
  663. end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP)
  664. local_EncodeVarint = _EncodeVarint
  665. def EncodeField(write, value, deterministic):
  666. write(start_bytes)
  667. local_EncodeVarint(write, value.ByteSize(), deterministic)
  668. value._InternalSerialize(write, deterministic)
  669. return write(end_bytes)
  670. return EncodeField
  671. # --------------------------------------------------------------------
  672. # As before, Map is special.
  673. def MapEncoder(
  674. field_descriptor, key_encoder, value_encoder, key_sizer, value_sizer
  675. ):
  676. """Encoder for map fields.
  677. Maps always have a wire format like this:
  678. message MapEntry {
  679. key_type key = 1;
  680. value_type value = 2;
  681. }
  682. repeated MapEntry map = N;
  683. """
  684. tag_bytes = TagBytes(
  685. field_descriptor.number, wire_format.WIRETYPE_LENGTH_DELIMITED
  686. )
  687. local_EncodeVarint = _EncodeVarint
  688. def EncodeField(write, value, deterministic):
  689. value_keys = sorted(value.keys()) if deterministic else value
  690. for key in value_keys:
  691. val = value[key]
  692. entry_size = key_sizer(key) + value_sizer(val)
  693. write(tag_bytes)
  694. local_EncodeVarint(write, entry_size, deterministic)
  695. key_encoder(write, key, deterministic)
  696. value_encoder(write, val, deterministic)
  697. return EncodeField