OLD | NEW |
(Empty) | |
| 1 # Protocol Buffers - Google's data interchange format |
| 2 # Copyright 2008 Google Inc. All rights reserved. |
| 3 # http://code.google.com/p/protobuf/ |
| 4 # |
| 5 # Redistribution and use in source and binary forms, with or without |
| 6 # modification, are permitted provided that the following conditions are |
| 7 # met: |
| 8 # |
| 9 # * Redistributions of source code must retain the above copyright |
| 10 # notice, this list of conditions and the following disclaimer. |
| 11 # * Redistributions in binary form must reproduce the above |
| 12 # copyright notice, this list of conditions and the following disclaimer |
| 13 # in the documentation and/or other materials provided with the |
| 14 # distribution. |
| 15 # * Neither the name of Google Inc. nor the names of its |
| 16 # contributors may be used to endorse or promote products derived from |
| 17 # this software without specific prior written permission. |
| 18 # |
| 19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 |
| 31 """Provides a factory class for generating dynamic messages.""" |
| 32 |
| 33 __author__ = 'matthewtoia@google.com (Matt Toia)' |
| 34 |
| 35 from google.protobuf import descriptor_database |
| 36 from google.protobuf import descriptor_pool |
| 37 from google.protobuf import message |
| 38 from google.protobuf import reflection |
| 39 |
| 40 |
| 41 class MessageFactory(object): |
| 42 """Factory for creating Proto2 messages from descriptors in a pool.""" |
| 43 |
| 44 def __init__(self): |
| 45 """Initializes a new factory.""" |
| 46 self._classes = {} |
| 47 |
| 48 def GetPrototype(self, descriptor): |
| 49 """Builds a proto2 message class based on the passed in descriptor. |
| 50 |
| 51 Passing a descriptor with a fully qualified name matching a previous |
| 52 invocation will cause the same class to be returned. |
| 53 |
| 54 Args: |
| 55 descriptor: The descriptor to build from. |
| 56 |
| 57 Returns: |
| 58 A class describing the passed in descriptor. |
| 59 """ |
| 60 |
| 61 if descriptor.full_name not in self._classes: |
| 62 result_class = reflection.GeneratedProtocolMessageType( |
| 63 descriptor.name.encode('ascii', 'ignore'), |
| 64 (message.Message,), |
| 65 {'DESCRIPTOR': descriptor}) |
| 66 self._classes[descriptor.full_name] = result_class |
| 67 for field in descriptor.fields: |
| 68 if field.message_type: |
| 69 self.GetPrototype(field.message_type) |
| 70 return self._classes[descriptor.full_name] |
| 71 |
| 72 |
| 73 _DB = descriptor_database.DescriptorDatabase() |
| 74 _POOL = descriptor_pool.DescriptorPool(_DB) |
| 75 _FACTORY = MessageFactory() |
| 76 |
| 77 |
| 78 def GetMessages(file_protos): |
| 79 """Builds a dictionary of all the messages available in a set of files. |
| 80 |
| 81 Args: |
| 82 file_protos: A sequence of file protos to build messages out of. |
| 83 |
| 84 Returns: |
| 85 A dictionary containing all the message types in the files mapping the |
| 86 fully qualified name to a Message subclass for the descriptor. |
| 87 """ |
| 88 |
| 89 result = {} |
| 90 for file_proto in file_protos: |
| 91 _DB.Add(file_proto) |
| 92 for file_proto in file_protos: |
| 93 for desc in _GetAllDescriptors(file_proto.message_type, file_proto.package): |
| 94 result[desc.full_name] = _FACTORY.GetPrototype(desc) |
| 95 return result |
| 96 |
| 97 |
| 98 def _GetAllDescriptors(desc_protos, package): |
| 99 """Gets all levels of nested message types as a flattened list of descriptors. |
| 100 |
| 101 Args: |
| 102 desc_protos: The descriptor protos to process. |
| 103 package: The package where the protos are defined. |
| 104 |
| 105 Yields: |
| 106 Each message descriptor for each nested type. |
| 107 """ |
| 108 |
| 109 for desc_proto in desc_protos: |
| 110 name = '.'.join((package, desc_proto.name)) |
| 111 yield _POOL.FindMessageTypeByName(name) |
| 112 for nested_desc in _GetAllDescriptors(desc_proto.nested_type, name): |
| 113 yield nested_desc |
OLD | NEW |