diff options
Diffstat (limited to 'python/google/protobuf/reflection.py')
-rwxr-xr-x | python/google/protobuf/reflection.py | 96 |
1 files changed, 9 insertions, 87 deletions
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py index 82fca661..0c757264 100755 --- a/python/google/protobuf/reflection.py +++ b/python/google/protobuf/reflection.py @@ -49,101 +49,23 @@ __author__ = 'robinson@google.com (Will Robinson)' from google.protobuf.internal import api_implementation -from google.protobuf import descriptor as descriptor_mod from google.protobuf import message -_FieldDescriptor = descriptor_mod.FieldDescriptor - if api_implementation.Type() == 'cpp': from google.protobuf.pyext import cpp_message as message_impl else: from google.protobuf.internal import python_message as message_impl -_NewMessage = message_impl.NewMessage -_InitMessage = message_impl.InitMessage - - -class GeneratedProtocolMessageType(type): - - """Metaclass for protocol message classes created at runtime from Descriptors. - - We add implementations for all methods described in the Message class. We - also create properties to allow getting/setting all fields in the protocol - message. Finally, we create slots to prevent users from accidentally - "setting" nonexistent fields in the protocol message, which then wouldn't get - serialized / deserialized properly. - - The protocol compiler currently uses this metaclass to create protocol - message classes at runtime. Clients can also manually create their own - classes at runtime, as in this example: - - mydescriptor = Descriptor(.....) - class MyProtoClass(Message): - __metaclass__ = GeneratedProtocolMessageType - DESCRIPTOR = mydescriptor - myproto_instance = MyProtoClass() - myproto.foo_field = 23 - ... - - The above example will not work for nested types. If you wish to include them, - use reflection.MakeClass() instead of manually instantiating the class in - order to create the appropriate class structure. - """ - - # Must be consistent with the protocol-compiler code in - # proto2/compiler/internal/generator.*. - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __new__(cls, name, bases, dictionary): - """Custom allocation for runtime-generated class types. - - We override __new__ because this is apparently the only place - where we can meaningfully set __slots__ on the class we're creating(?). - (The interplay between metaclasses and slots is not very well-documented). - - Args: - name: Name of the class (ignored, but required by the - metaclass protocol). - bases: Base classes of the class we're constructing. - (Should be message.Message). We ignore this field, but - it's required by the metaclass protocol - dictionary: The class dictionary of the class we're - constructing. dictionary[_DESCRIPTOR_KEY] must contain - a Descriptor object describing this protocol message - type. - - Returns: - Newly-allocated class. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - bases = _NewMessage(bases, descriptor, dictionary) - superclass = super(GeneratedProtocolMessageType, cls) - - new_class = superclass.__new__(cls, name, bases, dictionary) - return new_class - - def __init__(cls, name, bases, dictionary): - """Here we perform the majority of our work on the class. - We add enum getters, an __init__ method, implementations - of all Message methods, and properties for all fields - in the protocol type. - - Args: - name: Name of the class (ignored, but required by the - metaclass protocol). - bases: Base classes of the class we're constructing. - (Should be message.Message). We ignore this field, but - it's required by the metaclass protocol - dictionary: The class dictionary of the class we're - constructing. dictionary[_DESCRIPTOR_KEY] must contain - a Descriptor object describing this protocol message - type. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - _InitMessage(descriptor, cls) - superclass = super(GeneratedProtocolMessageType, cls) - superclass.__init__(name, bases, dictionary) +# The type of all Message classes. +# Part of the public interface. +# +# Used by generated files, but clients can also use it at runtime: +# mydescriptor = pool.FindDescriptor(.....) +# class MyProtoClass(Message): +# __metaclass__ = GeneratedProtocolMessageType +# DESCRIPTOR = mydescriptor +GeneratedProtocolMessageType = message_impl.GeneratedProtocolMessageType def ParseMessage(descriptor, byte_str): |