Index: third_party/protobuf/python/google/protobuf/proto_builder.py |
diff --git a/third_party/protobuf/python/google/protobuf/proto_builder.py b/third_party/protobuf/python/google/protobuf/proto_builder.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..736caed385947c5c0c446b86a4d9592571d33326 |
--- /dev/null |
+++ b/third_party/protobuf/python/google/protobuf/proto_builder.py |
@@ -0,0 +1,130 @@ |
+# Protocol Buffers - Google's data interchange format |
+# Copyright 2008 Google Inc. All rights reserved. |
+# https://developers.google.com/protocol-buffers/ |
+# |
+# Redistribution and use in source and binary forms, with or without |
+# modification, are permitted provided that the following conditions are |
+# met: |
+# |
+# * Redistributions of source code must retain the above copyright |
+# notice, this list of conditions and the following disclaimer. |
+# * Redistributions in binary form must reproduce the above |
+# copyright notice, this list of conditions and the following disclaimer |
+# in the documentation and/or other materials provided with the |
+# distribution. |
+# * Neither the name of Google Inc. nor the names of its |
+# contributors may be used to endorse or promote products derived from |
+# this software without specific prior written permission. |
+# |
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+"""Dynamic Protobuf class creator.""" |
+ |
+try: |
+ from collections import OrderedDict |
+except ImportError: |
+ from ordereddict import OrderedDict #PY26 |
+import hashlib |
+import os |
+ |
+from google.protobuf import descriptor_pb2 |
+from google.protobuf import message_factory |
+ |
+ |
+def _GetMessageFromFactory(factory, full_name): |
+ """Get a proto class from the MessageFactory by name. |
+ |
+ Args: |
+ factory: a MessageFactory instance. |
+ full_name: str, the fully qualified name of the proto type. |
+ Returns: |
+ A class, for the type identified by full_name. |
+ Raises: |
+ KeyError, if the proto is not found in the factory's descriptor pool. |
+ """ |
+ proto_descriptor = factory.pool.FindMessageTypeByName(full_name) |
+ proto_cls = factory.GetPrototype(proto_descriptor) |
+ return proto_cls |
+ |
+ |
+def MakeSimpleProtoClass(fields, full_name=None, pool=None): |
+ """Create a Protobuf class whose fields are basic types. |
+ |
+ Note: this doesn't validate field names! |
+ |
+ Args: |
+ fields: dict of {name: field_type} mappings for each field in the proto. If |
+ this is an OrderedDict the order will be maintained, otherwise the |
+ fields will be sorted by name. |
+ full_name: optional str, the fully-qualified name of the proto type. |
+ pool: optional DescriptorPool instance. |
+ Returns: |
+ a class, the new protobuf class with a FileDescriptor. |
+ """ |
+ factory = message_factory.MessageFactory(pool=pool) |
+ |
+ if full_name is not None: |
+ try: |
+ proto_cls = _GetMessageFromFactory(factory, full_name) |
+ return proto_cls |
+ except KeyError: |
+ # The factory's DescriptorPool doesn't know about this class yet. |
+ pass |
+ |
+ # Get a list of (name, field_type) tuples from the fields dict. If fields was |
+ # an OrderedDict we keep the order, but otherwise we sort the field to ensure |
+ # consistent ordering. |
+ field_items = fields.items() |
+ if not isinstance(fields, OrderedDict): |
+ field_items = sorted(field_items) |
+ |
+ # Use a consistent file name that is unlikely to conflict with any imported |
+ # proto files. |
+ fields_hash = hashlib.sha1() |
+ for f_name, f_type in field_items: |
+ fields_hash.update(f_name.encode('utf-8')) |
+ fields_hash.update(str(f_type).encode('utf-8')) |
+ proto_file_name = fields_hash.hexdigest() + '.proto' |
+ |
+ # If the proto is anonymous, use the same hash to name it. |
+ if full_name is None: |
+ full_name = ('net.proto2.python.public.proto_builder.AnonymousProto_' + |
+ fields_hash.hexdigest()) |
+ try: |
+ proto_cls = _GetMessageFromFactory(factory, full_name) |
+ return proto_cls |
+ except KeyError: |
+ # The factory's DescriptorPool doesn't know about this class yet. |
+ pass |
+ |
+ # This is the first time we see this proto: add a new descriptor to the pool. |
+ factory.pool.Add( |
+ _MakeFileDescriptorProto(proto_file_name, full_name, field_items)) |
+ return _GetMessageFromFactory(factory, full_name) |
+ |
+ |
+def _MakeFileDescriptorProto(proto_file_name, full_name, field_items): |
+ """Populate FileDescriptorProto for MessageFactory's DescriptorPool.""" |
+ package, name = full_name.rsplit('.', 1) |
+ file_proto = descriptor_pb2.FileDescriptorProto() |
+ file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name) |
+ file_proto.package = package |
+ desc_proto = file_proto.message_type.add() |
+ desc_proto.name = name |
+ for f_number, (f_name, f_type) in enumerate(field_items, 1): |
+ field_proto = desc_proto.field.add() |
+ field_proto.name = f_name |
+ field_proto.number = f_number |
+ field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL |
+ field_proto.type = f_type |
+ return file_proto |