diff options
Diffstat (limited to 'python/google/protobuf/proto_builder.py')
-rw-r--r-- | python/google/protobuf/proto_builder.py | 43 |
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 |