aboutsummaryrefslogtreecommitdiffhomepage
path: root/python/google/protobuf/proto_builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/proto_builder.py')
-rw-r--r--python/google/protobuf/proto_builder.py43
1 files changed, 31 insertions, 12 deletions
diff --git a/python/google/protobuf/proto_builder.py b/python/google/protobuf/proto_builder.py
index 700e3c25..736caed3 100644
--- a/python/google/protobuf/proto_builder.py
+++ b/python/google/protobuf/proto_builder.py
@@ -48,7 +48,7 @@ def _GetMessageFromFactory(factory, full_name):
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.
+ A class, for the type identified by full_name.
Raises:
KeyError, if the proto is not found in the factory's descriptor pool.
"""
@@ -57,7 +57,7 @@ def _GetMessageFromFactory(factory, full_name):
return proto_cls
-def MakeSimpleProtoClass(fields, full_name, pool=None):
+def MakeSimpleProtoClass(fields, full_name=None, pool=None):
"""Create a Protobuf class whose fields are basic types.
Note: this doesn't validate field names!
@@ -66,18 +66,20 @@ def MakeSimpleProtoClass(fields, full_name, pool=None):
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: str, the fully-qualified name of the proto type.
+ 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)
- try:
- proto_cls = _GetMessageFromFactory(factory, full_name)
- return proto_cls
- except KeyError:
- # The factory's DescriptorPool doesn't know about this class yet.
- pass
+
+ 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
@@ -94,6 +96,25 @@ def MakeSimpleProtoClass(fields, full_name, pool=None):
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)
@@ -106,6 +127,4 @@ def MakeSimpleProtoClass(fields, full_name, pool=None):
field_proto.number = f_number
field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
field_proto.type = f_type
-
- factory.pool.Add(file_proto)
- return _GetMessageFromFactory(factory, full_name)
+ return file_proto