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# This code is meant to work on Python 2.4 and above only. 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# TODO(robinson): Helpers for verbose, common checks like seeing if a 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# descriptor's cpp_type is CPPTYPE_MESSAGE. 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville"""Contains a metaclass and helper functions used to create 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleprotocol message classes from Descriptor objects at runtime. 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleRecall that a metaclass is the "type" of a class. 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville(A class is to a metaclass what an instance is to a class.) 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIn this case, we use the GeneratedProtocolMessageType metaclass 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleto inject all the useful functionality into the classes 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleoutput by the protocol compiler at compile-time. 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleThe upshot of all this is that the real implementation 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledetails for ALL pure-Python protocol buffers are *here in 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillethis file*. 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville""" 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville__author__ = 'robinson@google.com (Will Robinson)' 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 53d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilletry: 54d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville from cStringIO import StringIO 55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleexcept ImportError: 56d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville from StringIO import StringIO 57d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleimport struct 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport weakref 59d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# We use "as" to avoid name collisions with variables. 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import containers 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import decoder 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import encoder 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import message_listener as message_listener_mod 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import type_checkers 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf.internal import wire_format 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf import descriptor as descriptor_mod 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf import message as message_mod 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillefrom google.protobuf import text_format 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville_FieldDescriptor = descriptor_mod.FieldDescriptor 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass GeneratedProtocolMessageType(type): 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Metaclass for protocol message classes created at runtime from Descriptors. 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville We add implementations for all methods described in the Message class. We 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville also create properties to allow getting/setting all fields in the protocol 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message. Finally, we create slots to prevent users from accidentally 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "setting" nonexistent fields in the protocol message, which then wouldn't get 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville serialized / deserialized properly. 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville The protocol compiler currently uses this metaclass to create protocol 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message classes at runtime. Clients can also manually create their own 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville classes at runtime, as in this example: 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville mydescriptor = Descriptor(.....) 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville class MyProtoClass(Message): 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville __metaclass__ = GeneratedProtocolMessageType 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DESCRIPTOR = mydescriptor 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville myproto_instance = MyProtoClass() 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville myproto.foo_field = 23 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ... 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Must be consistent with the protocol-compiler code in 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # proto2/compiler/internal/generator.*. 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _DESCRIPTOR_KEY = 'DESCRIPTOR' 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def __new__(cls, name, bases, dictionary): 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Custom allocation for runtime-generated class types. 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville We override __new__ because this is apparently the only place 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville where we can meaningfully set __slots__ on the class we're creating(?). 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (The interplay between metaclasses and slots is not very well-documented). 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville name: Name of the class (ignored, but required by the 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville metaclass protocol). 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bases: Base classes of the class we're constructing. 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (Should be message.Message). We ignore this field, but 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville it's required by the metaclass protocol 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dictionary: The class dictionary of the class we're 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville constructing. dictionary[_DESCRIPTOR_KEY] must contain 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville a Descriptor object describing this protocol message 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type. 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Returns: 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Newly-allocated class. 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddSlots(descriptor, dictionary) 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddClassAttributesForNestedExtensions(descriptor, dictionary) 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville superclass = super(GeneratedProtocolMessageType, cls) 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return superclass.__new__(cls, name, bases, dictionary) 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def __init__(cls, name, bases, dictionary): 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Here we perform the majority of our work on the class. 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville We add enum getters, an __init__ method, implementations 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville of all Message methods, and properties for all fields 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville in the protocol type. 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville name: Name of the class (ignored, but required by the 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville metaclass protocol). 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bases: Base classes of the class we're constructing. 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (Should be message.Message). We ignore this field, but 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville it's required by the metaclass protocol 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dictionary: The class dictionary of the class we're 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville constructing. dictionary[_DESCRIPTOR_KEY] must contain 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville a Descriptor object describing this protocol message 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type. 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] 146d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._decoders_by_tag = {} 148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._extensions_by_name = {} 149d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._extensions_by_number = {} 150d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (descriptor.has_options and 151d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville descriptor.GetOptions().message_set_wire_format): 152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( 153d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville decoder.MessageSetItemDecoder(cls._extensions_by_number)) 154d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # We act as a "friend" class of the descriptor, setting 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # its _concrete_class attribute the first time we use a 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # given descriptor to initialize a concrete protocol message 158d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # class. We also attach stuff to each FieldDescriptor for quick 159d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # lookup later on. 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville concrete_class_attr_name = '_concrete_class' 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if not hasattr(descriptor, concrete_class_attr_name): 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setattr(descriptor, concrete_class_attr_name, cls) 163d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field in descriptor.fields: 164d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AttachFieldHelpers(cls, field) 165d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddEnumValues(descriptor, cls) 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddInitMethod(descriptor, cls) 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddPropertiesForFields(descriptor, cls) 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddPropertiesForExtensions(descriptor, cls) 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddStaticMethods(cls) 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddMessageMethods(descriptor, cls) 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddPrivateHelperMethods(cls) 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville superclass = super(GeneratedProtocolMessageType, cls) 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville superclass.__init__(name, bases, dictionary) 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Stateless helpers for GeneratedProtocolMessageType below. 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Outside clients should not access these directly. 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# I opted not to make any of these methods on the metaclass, to make it more 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# clear that I'm not really using any state there and to keep clients from 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# thinking that they have direct access to these construction helpers. 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _PropertyName(proto_field_name): 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Returns the name of the public property attribute which 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville clients can use to get and (in some cases) set the value 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville of a protocol message field. 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto_field_name: The protocol message field name, exactly 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville as it appears (or would appear) in a .proto file. 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # TODO(robinson): Escape Python keywords (e.g., yield), and test this support. 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # nnorwitz makes my day by writing: 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # """ 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # FYI. See the keyword module in the stdlib. This could be as simple as: 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # if keyword.iskeyword(proto_field_name): 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # return proto_field_name + "_" 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # return proto_field_name 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # """ 203d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Kenton says: The above is a BAD IDEA. People rely on being able to use 204d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # getattr() and setattr() to reflectively manipulate field values. If we 205d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # rename the properties, then every such user has to also make sure to apply 206d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # the same transformation. Note that currently if you name a field "yield", 207d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # you can still access it just fine using getattr/setattr -- it's not even 208d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # that cumbersome to do so. 209d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # TODO(kenton): Remove this method entirely if/when everyone agrees with my 210d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # position. 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return proto_field_name 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 214d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _VerifyExtensionHandle(message, extension_handle): 215d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Verify that the given extension handle is valid.""" 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not isinstance(extension_handle, _FieldDescriptor): 218d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise KeyError('HasExtension() expects an extension handle, got: %s' % 219d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension_handle) 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 221d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not extension_handle.is_extension: 222d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise KeyError('"%s" is not an extension.' % extension_handle.full_name) 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 224d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if extension_handle.containing_type is not message.DESCRIPTOR: 225d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise KeyError('Extension "%s" extends message type "%s", but this ' 226d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 'message is of type "%s".' % 227d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (extension_handle.full_name, 228d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension_handle.containing_type.full_name, 229d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message.DESCRIPTOR.full_name)) 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddSlots(message_descriptor, dictionary): 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds a __slots__ entry to dictionary, containing the names of all valid 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville attributes for this message type. 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_descriptor: A Descriptor instance describing this message type. 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dictionary: Class dictionary to which we'll add a '__slots__' entry. 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 240d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville dictionary['__slots__'] = ['_cached_byte_size', 241d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville '_cached_byte_size_dirty', 242d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville '_fields', 243d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville '_is_present_in_parent', 244d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville '_listener', 245d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville '_listener_for_children', 246d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville '__weakref__'] 247d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 248d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 249d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _IsMessageSetExtension(field): 250d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return (field.is_extension and 251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field.containing_type.has_options and 252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field.containing_type.GetOptions().message_set_wire_format and 253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field.type == _FieldDescriptor.TYPE_MESSAGE and 254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field.message_type == field.extension_scope and 255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field.label == _FieldDescriptor.LABEL_OPTIONAL) 256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 258d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _AttachFieldHelpers(cls, field_descriptor): 259d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) 260d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville is_packed = (field_descriptor.has_options and 261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor.GetOptions().packed) 262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 263d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if _IsMessageSetExtension(field_descriptor): 264d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) 265d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville sizer = encoder.MessageSetItemSizer(field_descriptor.number) 266d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( 268d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor.number, is_repeated, is_packed) 269d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( 270d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor.number, is_repeated, is_packed) 271d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 272d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor._encoder = field_encoder 273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor._sizer = sizer 274d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor._default_constructor = _DefaultValueConstructorForField( 275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor) 276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def AddDecoder(wiretype, is_packed): 278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) 279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._decoders_by_tag[tag_bytes] = ( 280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville type_checkers.TYPE_TO_DECODER[field_descriptor.type]( 281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor.number, is_repeated, is_packed, 282d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor, field_descriptor._default_constructor)) 283d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], 285d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville False) 286d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 287d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if is_repeated and wire_format.IsTypePackable(field_descriptor.type): 288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # To support wire compatibility of adding packed = true, add a decoder for 289d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # packed values regardless of the field's options. 290d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddClassAttributesForNestedExtensions(descriptor, dictionary): 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extension_dict = descriptor.extensions_by_name 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for extension_name, extension_field in extension_dict.iteritems(): 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert extension_name not in dictionary 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dictionary[extension_name] = extension_field 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddEnumValues(descriptor, cls): 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Sets class-level attributes for all enum fields defined in this message. 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville descriptor: Descriptor object for this message type. 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls: Class we're constructing for this message type. 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for enum_type in descriptor.enum_types: 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for enum_value in enum_type.values: 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setattr(cls, enum_value.name, enum_value.number) 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 312d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _DefaultValueConstructorForField(field): 313d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns a function which returns a default value for a field. 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 316d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field: FieldDescriptor object for this field. 317d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 318d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville The returned function has one argument: 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message: Message instance containing this field, or a weakref proxy 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville of same. 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville That function in turn returns a default value for this field. The default 323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value may refer back to |message| via a weak reference. 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 325d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if field.label == _FieldDescriptor.LABEL_REPEATED: 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if field.default_value != []: 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville raise ValueError('Repeated field default value not empty list: %s' % ( 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field.default_value)) 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # We can't look at _concrete_class yet since it might not have 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # been set. (Depends on order in which we initialize the classes). 333d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message_type = field.message_type 334d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def MakeRepeatedMessageDefault(message): 335d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return containers.RepeatedCompositeFieldContainer( 336d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message._listener_for_children, field.message_type) 337d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return MakeRepeatedMessageDefault 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 339d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) 340d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def MakeRepeatedScalarDefault(message): 341d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return containers.RepeatedScalarFieldContainer( 342d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message._listener_for_children, type_checker) 343d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return MakeRepeatedScalarDefault 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 346d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # _concrete_class may not yet be initialized. 347d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message_type = field.message_type 348d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def MakeSubMessageDefault(message): 349d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = message_type._concrete_class() 350d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result._SetListener(message._listener_for_children) 351d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 352d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return MakeSubMessageDefault 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def MakeScalarDefault(message): 355d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return field.default_value 356d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return MakeScalarDefault 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddInitMethod(message_descriptor, cls): 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds an __init__ method to cls.""" 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fields = message_descriptor.fields 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def init(self, **kwargs): 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._cached_byte_size = 0 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._cached_byte_size_dirty = False 365d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._fields = {} 366d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._is_present_in_parent = False 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._listener = message_listener_mod.NullMessageListener() 368d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._listener_for_children = _Listener(self) 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for field_name, field_value in kwargs.iteritems(): 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = _GetFieldByName(message_descriptor, field_name) 371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field is None: 372d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise TypeError("%s() got an unexpected keyword argument '%s'" % 373d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (message_descriptor.name, field_name)) 374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.label == _FieldDescriptor.LABEL_REPEATED: 375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville copy = field._default_constructor(self) 376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite 377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for val in field_value: 378d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville copy.add().MergeFrom(val) 379d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: # Scalar 380d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville copy.extend(field_value) 381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._fields[field] = copy 382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 383d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville copy = field._default_constructor(self) 384d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville copy.MergeFrom(field_value) 385d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._fields[field] = copy 386d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 387d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._fields[field] = field_value 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville init.__module__ = None 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville init.__doc__ = None 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.__init__ = init 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _GetFieldByName(message_descriptor, field_name): 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Returns a field descriptor by field name. 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_descriptor: A Descriptor describing all fields in message. 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_name: The name of the field to retrieve. 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Returns: 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville The field descriptor associated with the field name. 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try: 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return message_descriptor.fields_by_name[field_name] 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville except KeyError: 406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville raise ValueError('Protocol message has no "%s" field.' % field_name) 407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddPropertiesForFields(descriptor, cls): 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds properties for all fields in this protocol message type.""" 411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for field in descriptor.fields: 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddPropertiesForField(field, cls) 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 414d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if descriptor.is_extendable: 415d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # _ExtensionDict is just an adaptor with no state so we allocate a new one 416d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # every time it is accessed. 417d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls.Extensions = property(lambda self: _ExtensionDict(self)) 418d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddPropertiesForField(field, cls): 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds a public property for a protocol message field. 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Clients can use this property to get and (in the case 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville of non-repeated scalar fields) directly set the value 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville of a protocol message field. 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field: A FieldDescriptor for this field. 428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls: The class we're constructing. 429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Catch it if we add other types that we should 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # handle specially here. 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert _FieldDescriptor.MAX_CPPTYPE == 10 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville constant_name = field.name.upper() + "_FIELD_NUMBER" 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setattr(cls, constant_name, field.number) 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if field.label == _FieldDescriptor.LABEL_REPEATED: 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddPropertiesForRepeatedField(field, cls) 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddPropertiesForNonRepeatedCompositeField(field, cls) 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddPropertiesForNonRepeatedScalarField(field, cls) 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddPropertiesForRepeatedField(field, cls): 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds a public property for a "repeated" protocol message field. Clients 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville can use this property to get the value of the field, which will be either a 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville below). 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Note that when clients add values to these containers, we perform 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type-checking in the case of repeated scalar fields, and we also set any 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville necessary "has" bits as a side-effect. 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field: A FieldDescriptor for this field. 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls: The class we're constructing. 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto_field_name = field.name 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville property_name = _PropertyName(proto_field_name) 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def getter(self): 463d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = self._fields.get(field) 464d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field_value is None: 465d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Construct a new object to represent this field. 466d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = field._default_constructor(self) 467d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 468d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Atomically check if another thread has preempted us and, if not, swap 469d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in the new object we just created. If someone has preempted us, we 470d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # take that object and discard ours. 471d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # WARNING: We are relying on setdefault() being atomic. This is true 472d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in CPython but we haven't investigated others. This warning appears 473d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in several other locations in this file. 474d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = self._fields.setdefault(field, field_value) 475d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return field_value 476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville getter.__module__ = None 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville getter.__doc__ = 'Getter for %s.' % proto_field_name 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # We define a setter just so we can throw an exception with a more 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # helpful error message. 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def setter(self, new_value): 482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville raise AttributeError('Assignment not allowed to repeated field ' 483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville '"%s" in protocol message object.' % proto_field_name) 484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name 486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setattr(cls, property_name, property(getter, setter, doc=doc)) 487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddPropertiesForNonRepeatedScalarField(field, cls): 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds a public property for a nonrepeated, scalar protocol message field. 491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Clients can use this property to get and directly set the value of the field. 492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Note that when the client sets the value of a field by using this property, 493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville all necessary "has" bits are set as a side-effect, and we also perform 494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type-checking. 495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field: A FieldDescriptor for this field. 498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls: The class we're constructing. 499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto_field_name = field.name 501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville property_name = _PropertyName(proto_field_name) 502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) 503d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville default_value = field.default_value 504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def getter(self): 506d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return self._fields.get(field, default_value) 507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville getter.__module__ = None 508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville getter.__doc__ = 'Getter for %s.' % proto_field_name 509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def setter(self, new_value): 510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type_checker.CheckValue(new_value) 511d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._fields[field] = new_value 512d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Check _cached_byte_size_dirty inline to improve performance, since scalar 513d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # setters are called frequently. 514d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not self._cached_byte_size_dirty: 515d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._Modified() 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setter.__module__ = None 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setter.__doc__ = 'Setter for %s.' % proto_field_name 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Add a property to encapsulate the getter/setter. 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setattr(cls, property_name, property(getter, setter, doc=doc)) 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddPropertiesForNonRepeatedCompositeField(field, cls): 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds a public property for a nonrepeated, composite protocol message field. 526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville A composite field is a "group" or "message" field. 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Clients can use this property to get the value of the field, but cannot 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assign to the property directly. 530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field: A FieldDescriptor for this field. 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls: The class we're constructing. 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # TODO(robinson): Remove duplication with similar method 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # for non-repeated scalars. 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto_field_name = field.name 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville property_name = _PropertyName(proto_field_name) 539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_type = field.message_type 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def getter(self): 542d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = self._fields.get(field) 543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if field_value is None: 544d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Construct a new object to represent this field. 545d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = message_type._concrete_class() 546d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value._SetListener(self._listener_for_children) 547d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 548d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Atomically check if another thread has preempted us and, if not, swap 549d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in the new object we just created. If someone has preempted us, we 550d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # take that object and discard ours. 551d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # WARNING: We are relying on setdefault() being atomic. This is true 552d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in CPython but we haven't investigated others. This warning appears 553d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in several other locations in this file. 554d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = self._fields.setdefault(field, field_value) 555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return field_value 556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville getter.__module__ = None 557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville getter.__doc__ = 'Getter for %s.' % proto_field_name 558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # We define a setter just so we can throw an exception with a more 560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # helpful error message. 561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def setter(self, new_value): 562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville raise AttributeError('Assignment not allowed to composite field ' 563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville '"%s" in protocol message object.' % proto_field_name) 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Add a property to encapsulate the getter. 566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setattr(cls, property_name, property(getter, setter, doc=doc)) 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddPropertiesForExtensions(descriptor, cls): 571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds properties for all fields in this protocol message type.""" 572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extension_dict = descriptor.extensions_by_name 573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for extension_name, extension_field in extension_dict.iteritems(): 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville constant_name = extension_name.upper() + "_FIELD_NUMBER" 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville setattr(cls, constant_name, extension_field.number) 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddStaticMethods(cls): 579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # TODO(robinson): This probably needs to be thread-safe(?) 580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def RegisterExtension(extension_handle): 581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extension_handle.containing_type = cls.DESCRIPTOR 582d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AttachFieldHelpers(cls, extension_handle) 583d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 584d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Try to insert our extension, failing if an extension with the same number 585d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # already exists. 586d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville actual_handle = cls._extensions_by_number.setdefault( 587d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension_handle.number, extension_handle) 588d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if actual_handle is not extension_handle: 589d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise AssertionError( 590d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 'Extensions "%s" and "%s" both try to extend message type "%s" with ' 591d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 'field number %d.' % 592d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (extension_handle.full_name, actual_handle.full_name, 593d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls.DESCRIPTOR.full_name, extension_handle.number)) 594d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 595d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._extensions_by_name[extension_handle.full_name] = extension_handle 596d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 597d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville handle = extension_handle # avoid line wrapping 598d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if _IsMessageSetExtension(handle): 599d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # MessageSet extension. Also register under type name. 600d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._extensions_by_name[ 601d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension_handle.message_type.full_name] = extension_handle 602d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.RegisterExtension = staticmethod(RegisterExtension) 604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def FromString(s): 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message = cls() 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message.MergeFromString(s) 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return message 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.FromString = staticmethod(FromString) 610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 612d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _IsPresent(item): 613d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Given a (FieldDescriptor, value) tuple from _fields, return true if the 614d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value should be included in the list returned by ListFields().""" 615d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 616d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if item[0].label == _FieldDescriptor.LABEL_REPEATED: 617d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return bool(item[1]) 618d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 619d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return item[1]._is_present_in_parent 620d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 621d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return True 622d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 623d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddListFieldsMethod(message_descriptor, cls): 625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def ListFields(self): 628d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)] 629d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville all_fields.sort(key = lambda item: item[0].number) 630d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return all_fields 631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.ListFields = ListFields 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 634d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 635d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _AddHasFieldMethod(message_descriptor, cls): 636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 637d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 638d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville singular_fields = {} 639d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field in message_descriptor.fields: 640d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.label != _FieldDescriptor.LABEL_REPEATED: 641d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville singular_fields[field.name] = field 642d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def HasField(self, field_name): 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try: 645d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field = singular_fields[field_name] 646d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville except KeyError: 647d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise ValueError( 648d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 'Protocol message has no singular "%s" field.' % field_name) 649d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 650d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 651d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = self._fields.get(field) 652d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return value is not None and value._is_present_in_parent 653d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 654d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return field in self._fields 655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.HasField = HasField 656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 658d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _AddClearFieldMethod(message_descriptor, cls): 659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def ClearField(self, field_name): 661d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville try: 662d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field = message_descriptor.fields_by_name[field_name] 663d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville except KeyError: 664d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise ValueError('Protocol message has no "%s" field.' % field_name) 665d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 666d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field in self._fields: 667d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Note: If the field is a sub-message, its listener will still point 668d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # at us. That's fine, because the worst than can happen is that it 669d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # will call _Modified() and invalidate our byte size. Big deal. 670d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville del self._fields[field] 671d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 672d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Always call _Modified() -- even if nothing was changed, this is 673d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # a mutating method, and thus calling it should cause the field to become 674d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # present in the parent message. 675d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._Modified() 676d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.ClearField = ClearField 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddClearExtensionMethod(cls): 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def ClearExtension(self, extension_handle): 683d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _VerifyExtensionHandle(self, extension_handle) 684d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 685d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Similar to ClearField(), above. 686d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if extension_handle in self._fields: 687d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville del self._fields[extension_handle] 688d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._Modified() 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.ClearExtension = ClearExtension 690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 692d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _AddClearMethod(message_descriptor, cls): 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def Clear(self): 695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Clear fields. 696d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._fields = {} 697d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._Modified() 698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.Clear = Clear 699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddHasExtensionMethod(cls): 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def HasExtension(self, extension_handle): 704d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _VerifyExtensionHandle(self, extension_handle) 705d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: 706d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise KeyError('"%s" is repeated.' % extension_handle.full_name) 707d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 708d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 709d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville value = self._fields.get(extension_handle) 710d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return value is not None and value._is_present_in_parent 711d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 712d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return extension_handle in self._fields 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.HasExtension = HasExtension 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddEqualsMethod(message_descriptor, cls): 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def __eq__(self, other): 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (not isinstance(other, message_mod.Message) or 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville other.DESCRIPTOR != self.DESCRIPTOR): 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return False 722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if self is other: 724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return True 725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 726d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return self.ListFields() == other.ListFields() 727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.__eq__ = __eq__ 729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddStrMethod(message_descriptor, cls): 732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def __str__(self): 734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return text_format.MessageToString(self) 735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.__str__ = __str__ 736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddSetListenerMethod(cls): 739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def SetListener(self, listener): 741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if listener is None: 742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._listener = message_listener_mod.NullMessageListener() 743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._listener = listener 745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls._SetListener = SetListener 746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _BytesForNonRepeatedElement(value, field_number, field_type): 749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Returns the number of bytes needed to serialize a non-repeated element. 750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville The returned byte count includes space for tag information and any 751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville other additional space associated with serializing value. 752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value: Value we're serializing. 755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_number: Field number of this value. (Since the field number 756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville is stored as part of a varint-encoded tag, this has an impact 757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville on the total bytes required to serialize the value). 758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_type: The type of the field. One of the TYPE_* constants 759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville within FieldDescriptor. 760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try: 762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] 763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return fn(field_number, value) 764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville except KeyError: 765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) 766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddByteSizeMethod(message_descriptor, cls): 769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def ByteSize(self): 772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if not self._cached_byte_size_dirty: 773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return self._cached_byte_size 774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 0 776d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field_descriptor, field_value in self.ListFields(): 777d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size += field_descriptor._sizer(field_value) 778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._cached_byte_size = size 780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._cached_byte_size_dirty = False 781d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._listener_for_children.dirty = False 782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return size 783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.ByteSize = ByteSize 785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddSerializeToStringMethod(message_descriptor, cls): 788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def SerializeToString(self): 791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Check if the message has all of its required fields set. 792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errors = [] 793d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not self.IsInitialized(): 794d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise message_mod.EncodeError( 795d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 'Message is missing required fields: ' + 796d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ','.join(self.FindInitializationErrors())) 797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return self.SerializePartialToString() 798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.SerializeToString = SerializeToString 799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddSerializePartialToStringMethod(message_descriptor, cls): 802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Helper for _AddMessageMethods().""" 803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def SerializePartialToString(self): 805d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville out = StringIO() 806d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._InternalSerialize(out.write) 807d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return out.getvalue() 808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.SerializePartialToString = SerializePartialToString 809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 810d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def InternalSerialize(self, write_bytes): 811d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field_descriptor, field_value in self.ListFields(): 812d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_descriptor._encoder(write_bytes, field_value) 813d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._InternalSerialize = InternalSerialize 814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 816d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _AddMergeFromStringMethod(message_descriptor, cls): 817d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Helper for _AddMessageMethods().""" 818d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def MergeFromString(self, serialized): 819d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville length = len(serialized) 820d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville try: 821d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if self._InternalParse(serialized, 0, length) != length: 822d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # The only reason _InternalParse would return early is if it 823d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # encountered an end-group tag. 824d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise message_mod.DecodeError('Unexpected end-group tag.') 825d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville except IndexError: 826d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise message_mod.DecodeError('Truncated message.') 827d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville except struct.error, e: 828d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise message_mod.DecodeError(e) 829d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return length # Return this for legacy reasons. 830d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls.MergeFromString = MergeFromString 831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 832d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_ReadTag = decoder.ReadTag 833d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville local_SkipField = decoder.SkipField 834d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville decoders_by_tag = cls._decoders_by_tag 835d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 836d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def InternalParse(self, buffer, pos, end): 837d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._Modified() 838d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_dict = self._fields 839d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while pos != end: 840d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (tag_bytes, new_pos) = local_ReadTag(buffer, pos) 841d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_decoder = decoders_by_tag.get(tag_bytes) 842d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field_decoder is None: 843d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville new_pos = local_SkipField(buffer, new_pos, end, tag_bytes) 844d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if new_pos == -1: 845d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 846d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = new_pos 847d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 848d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pos = field_decoder(buffer, new_pos, end, self, field_dict) 849d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return pos 850d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._InternalParse = InternalParse 851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 853d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilledef _AddIsInitializedMethod(message_descriptor, cls): 854d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Adds the IsInitialized and FindInitializationError methods to the 855d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville protocol message class.""" 856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 857d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville required_fields = [field for field in message_descriptor.fields 858d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.label == _FieldDescriptor.LABEL_REQUIRED] 859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 860d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def IsInitialized(self, errors=None): 861d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Checks if all required fields of a message are set. 862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 863d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Args: 864d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors: A list which, if provided, will be populated with the field 865d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville paths of all missing required fields. 866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 867d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Returns: 868d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville True iff the specified message has all required fields set. 869d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 871d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Performance is critical so we avoid HasField() and ListFields(). 872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 873d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field in required_fields: 874d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (field not in self._fields or 875d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and 876d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville not self._fields[field]._is_present_in_parent)): 877d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if errors is not None: 878d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors.extend(self.FindInitializationErrors()) 879d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return False 880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 881d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field, value in self._fields.iteritems(): 882d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 883d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.label == _FieldDescriptor.LABEL_REPEATED: 884d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for element in value: 885d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not element.IsInitialized(): 886d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if errors is not None: 887d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors.extend(self.FindInitializationErrors()) 888d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return False 889d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif value._is_present_in_parent and not value.IsInitialized(): 890d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if errors is not None: 891d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors.extend(self.FindInitializationErrors()) 892d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return False 893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return True 895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 896d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls.IsInitialized = IsInitialized 897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 898d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def FindInitializationErrors(self): 899d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Finds required fields which are not initialized. 900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 901d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Returns: 902d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville A list of strings. Each string is a path to an uninitialized field from 903d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville the top-level message, e.g. "foo.bar[5].baz". 904d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 906d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors = [] # simplify things 907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 908d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field in required_fields: 909d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not self.HasField(field.name): 910d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors.append(field.name) 911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 912d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field, value in self.ListFields(): 913d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 914d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.is_extension: 915d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville name = "(%s)" % field.full_name 916d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 917d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville name = field.name 918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 919d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.label == _FieldDescriptor.LABEL_REPEATED: 920d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for i in xrange(len(value)): 921d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville element = value[i] 922d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville prefix = "%s[%d]." % (name, i) 923d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville sub_errors = element.FindInitializationErrors() 924d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors += [ prefix + error for error in sub_errors ] 925d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 926d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville prefix = name + "." 927d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville sub_errors = value.FindInitializationErrors() 928d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville errors += [ prefix + error for error in sub_errors ] 929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 930d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return errors 931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 932d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls.FindInitializationErrors = FindInitializationErrors 933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddMergeFromMethod(cls): 936d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED 937d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE 938d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def MergeFrom(self, msg): 940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert msg is not self 941d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._Modified() 942d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 943d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville fields = self._fields 944d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 945d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for field, value in msg._fields.iteritems(): 946d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field.label == LABEL_REPEATED or field.cpp_type == CPPTYPE_MESSAGE: 947d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = fields.get(field) 948d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if field_value is None: 949d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Construct a new object to represent this field. 950d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value = field._default_constructor(self) 951d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville fields[field] = field_value 952d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field_value.MergeFrom(value) 953d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 954d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._fields[field] = value 955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cls.MergeFrom = MergeFrom 956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddMessageMethods(message_descriptor, cls): 959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds implementations of all Message methods to cls.""" 960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddListFieldsMethod(message_descriptor, cls) 961d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AddHasFieldMethod(message_descriptor, cls) 962d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AddClearFieldMethod(message_descriptor, cls) 963d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if message_descriptor.is_extendable: 964d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AddClearExtensionMethod(cls) 965d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AddHasExtensionMethod(cls) 966d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AddClearMethod(message_descriptor, cls) 967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddEqualsMethod(message_descriptor, cls) 968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddStrMethod(message_descriptor, cls) 969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddSetListenerMethod(cls) 970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddByteSizeMethod(message_descriptor, cls) 971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddSerializeToStringMethod(message_descriptor, cls) 972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddSerializePartialToStringMethod(message_descriptor, cls) 973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddMergeFromStringMethod(message_descriptor, cls) 974d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _AddIsInitializedMethod(message_descriptor, cls) 975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _AddMergeFromMethod(cls) 976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _AddPrivateHelperMethods(cls): 979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Adds implementation of private helper methods to cls.""" 980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 981d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def Modified(self): 982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Sets the _cached_byte_size_dirty bit to true, 983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville and propagates this to our listener iff this was a state change. 984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 985d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 986d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Note: Some callers check _cached_byte_size_dirty before calling 987d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # _Modified() as an extra optimization. So, if this method is ever 988d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # changed such that it does stuff even when _cached_byte_size_dirty is 989d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # already true, the callers need to be updated. 990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if not self._cached_byte_size_dirty: 991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._cached_byte_size_dirty = True 992d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._listener_for_children.dirty = True 993d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._is_present_in_parent = True 994d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._listener.Modified() 995d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 996d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls._Modified = Modified 997d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville cls.SetInParent = Modified 998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass _Listener(object): 1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """MessageListener implementation that a parent message registers with its 1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville child message. 1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville In order to support semantics like: 1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1007d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville foo.bar.baz.qux = 23 1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert foo.HasField('bar') 1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ...child objects must have back references to their parents. 1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville This helper class is at the heart of this support. 1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1014d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def __init__(self, parent_message): 1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Args: 1016d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville parent_message: The message whose _Modified() method we should call when 1017d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville we receive Modified() messages. 1018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 1019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # This listener establishes a back reference from a child (contained) object 1020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # to its parent (containing) object. We make this a weak reference to avoid 1021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # creating cyclic garbage when the client finishes with the 'parent' object 1022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # in the tree. 1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if isinstance(parent_message, weakref.ProxyType): 1024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._parent_message_weakref = parent_message 1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville else: 1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville self._parent_message_weakref = weakref.proxy(parent_message) 1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1028d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # As an optimization, we also indicate directly on the listener whether 1029d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # or not the parent message is dirty. This way we can avoid traversing 1030d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # up the tree in the common case. 1031d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self.dirty = False 1032d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1033d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def Modified(self): 1034d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if self.dirty: 1035d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return 1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville try: 1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Propagate the signal to our parents iff this is the first field set. 1038d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._parent_message_weakref._Modified() 1039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville except ReferenceError: 1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # We can get here if a client has kept a reference to a child object, 1041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # and is now setting a field on it, but the child's parent has been 1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # garbage-collected. This is not an error. 1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pass 1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous... 1047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# TODO(robinson): Unify error handling of "unknown extension" crap. 1048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# TODO(robinson): Support iteritems()-style iteration over all 1049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# extensions with the "has" bits turned on? 1050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass _ExtensionDict(object): 1051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Dict-like container for supporting an indexable "Extensions" 1053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field on proto instances. 1054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Note that in all cases we expect extension handles to be 1056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptors. 1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 1058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1059d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def __init__(self, extended_message): 1060d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """extended_message: Message instance for which we are the Extensions dict. 1061d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """ 1062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1063d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._extended_message = extended_message 1064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1065d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville def __getitem__(self, extension_handle): 1066d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville """Returns the current value of the given extension handle.""" 1067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1068d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _VerifyExtensionHandle(self._extended_message, extension_handle) 1069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1070d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = self._extended_message._fields.get(extension_handle) 1071d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if result is not None: 1072d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1074d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: 1075d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = extension_handle._default_constructor(self._extended_message) 1076d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: 1077d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = extension_handle.message_type._concrete_class() 1078d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville try: 1079d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result._SetListener(self._extended_message._listener_for_children) 1080d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville except ReferenceError: 1081d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville pass 1082d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville else: 1083d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Singular scalar -- just return the default without inserting into the 1084d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # dict. 1085d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return extension_handle.default_value 1086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1087d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Atomically check if another thread has preempted us and, if not, swap 1088d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in the new object we just created. If someone has preempted us, we 1089d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # take that object and discard ours. 1090d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # WARNING: We are relying on setdefault() being atomic. This is true 1091d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in CPython but we haven't investigated others. This warning appears 1092d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # in several other locations in this file. 1093d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result = self._extended_message._fields.setdefault( 1094d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension_handle, result) 1095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1096d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return result 1097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def __eq__(self, other): 1099d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if not isinstance(other, self.__class__): 1100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return False 1101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville my_fields = self._extended_message.ListFields() 1103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville other_fields = other._extended_message.ListFields() 1104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1105d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # Get rid of non-extension fields. 1106d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville my_fields = [ field for field in my_fields if field.is_extension ] 1107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville other_fields = [ field for field in other_fields if field.is_extension ] 1108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return my_fields == other_fields 1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def __ne__(self, other): 1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return not self == other 1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville # Note that this is only meaningful for non-repeated, scalar extension 1115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # fields. Note also that we may have to call _Modified() when we do 1116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # successfully set a field this way, to set any necssary "has" bits in the 1117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # ancestors of the extended message. 1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def __setitem__(self, extension_handle, value): 1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """If extension_handle specifies a non-repeated, scalar extension 1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field, sets the value of that field. 1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1123d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville _VerifyExtensionHandle(self._extended_message, extension_handle) 1124d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1125d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or 1126d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE): 1127d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville raise TypeError( 1128d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 'Cannot assign to extension "%s" because it is a repeated or ' 1129d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 'composite type.' % extension_handle.full_name) 1130d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 1131d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # It's slightly wasteful to lookup the type checker each time, 1132d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville # but we expect this to be a vanishingly uncommon case anyway. 1133d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville type_checker = type_checkers.GetTypeChecker( 1134d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville extension_handle.cpp_type, extension_handle.type) 1135d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville type_checker.CheckValue(value) 1136d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._extended_message._fields[extension_handle] = value 1137d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville self._extended_message._Modified() 1138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville def _FindExtensionByName(self, name): 1140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """Tries to find a known extension with the specified name. 1141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Args: 1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville name: Extension full name. 1144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Returns: 1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Extension field descriptor. 1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville """ 1148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return self._extended_message._extensions_by_name.get(name, None) 1149