encoder
Code for encoding protocol message primitives.
Contains the logic for encoding every logical protocol field type into one of the 5 physical wire types.
This code is designed to push the Python interpreter's performance to the limits.
The basic idea is that at startup time, for every field (i.e. every FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The sizer takes a value of this field's type and computes its byte size. The encoder takes a writer function and a value. It encodes the value into byte strings and invokes the writer function to write those strings. Typically the writer function is the write() method of a BytesIO.
We try to do as much work as possible when constructing the writer and the sizer rather than when calling them. In particular: * We copy any needed global functions to local variables, so that we do not need to do costly global table lookups at runtime. * Similarly, we try to do any attribute lookups at startup time if possible. * Every field's tag is encoded to bytes at startup, since it can't change at runtime. * Whatever component of the field size we can compute at startup, we do. * We avoid sharing code if doing so would make the code slower and not sharing does not burden us too much. For example, encoders for repeated fields do not just call the encoders for singular fields in a loop because this would add an extra function call overhead for every loop iteration; instead, we manually inline the single-value encoder into the loop. * If a Python function lacks a return statement, Python actually generates instructions to pop the result of the last statement off the stack, push None onto the stack, and then return that. If we really don't care what value is returned, then we can save two instructions by returning the result of the last statement. It looks funny but it helps. * We assume that type and bounds checking has happened at a higher level.
BoolEncoder(field_number, is_repeated, is_packed)
Returns an encoder for a boolean field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 |
|
BytesEncoder(field_number, is_repeated, is_packed)
Returns an encoder for a bytes field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
|
BytesSizer(field_number, is_repeated, is_packed)
Returns a sizer for a bytes field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
|
GroupEncoder(field_number, is_repeated, is_packed)
Returns an encoder for a group field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 |
|
GroupSizer(field_number, is_repeated, is_packed)
Returns a sizer for a group field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
|
MapEncoder(field_descriptor)
Encoder for extensions of MessageSet.
Maps always have a wire format like this
message MapEntry { key_type key = 1; value_type value = 2; } repeated MapEntry map = N;
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 |
|
MapSizer(field_descriptor, is_message_map)
Returns a sizer for a map field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
|
MessageEncoder(field_number, is_repeated, is_packed)
Returns an encoder for a message field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 |
|
MessageSetItemEncoder(field_number)
Encoder for extensions of MessageSet.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
|
MessageSetItemSizer(field_number)
Returns a sizer for extensions of MessageSet.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
|
MessageSizer(field_number, is_repeated, is_packed)
Returns a sizer for a message field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
|
StringEncoder(field_number, is_repeated, is_packed)
Returns an encoder for a string field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
|
StringSizer(field_number, is_repeated, is_packed)
Returns a sizer for a string field.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
|
TagBytes(field_number, wire_type)
Encode the given tag and return the bytes. Only called at startup.
Source code in client/ayon_hiero/vendor/google/protobuf/internal/encoder.py
420 421 422 423 |
|