Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
proto_builder.py112 linesDownload Raw Back to protobuf
1# Protocol Buffers - Google's data interchange format2# Copyright 2008 Google Inc.  All rights reserved.3#4# Use of this source code is governed by a BSD-style5# license that can be found in the LICENSE file or at6# https://developers.google.com/open-source/licenses/bsd7 8"""Dynamic Protobuf class creator."""9 10from collections import OrderedDict11import hashlib12import os13 14from google.protobuf import descriptor_pb215from google.protobuf import descriptor16from google.protobuf import descriptor_pool17from google.protobuf import message_factory18 19 20def _GetMessageFromFactory(pool, full_name):21  """Get a proto class from the MessageFactory by name.22 23  Args:24    pool: a descriptor pool.25    full_name: str, the fully qualified name of the proto type.26  Returns:27    A class, for the type identified by full_name.28  Raises:29    KeyError, if the proto is not found in the factory's descriptor pool.30  """31  proto_descriptor = pool.FindMessageTypeByName(full_name)32  proto_cls = message_factory.GetMessageClass(proto_descriptor)33  return proto_cls34 35 36def MakeSimpleProtoClass(fields, full_name=None, pool=None):37  """Create a Protobuf class whose fields are basic types.38 39  Note: this doesn't validate field names!40 41  Args:42    fields: dict of {name: field_type} mappings for each field in the proto. If43        this is an OrderedDict the order will be maintained, otherwise the44        fields will be sorted by name.45    full_name: optional str, the fully-qualified name of the proto type.46    pool: optional DescriptorPool instance.47  Returns:48    a class, the new protobuf class with a FileDescriptor.49  """50  pool_instance = pool or descriptor_pool.DescriptorPool()51  if full_name is not None:52    try:53      proto_cls = _GetMessageFromFactory(pool_instance, full_name)54      return proto_cls55    except KeyError:56      # The factory's DescriptorPool doesn't know about this class yet.57      pass58 59  # Get a list of (name, field_type) tuples from the fields dict. If fields was60  # an OrderedDict we keep the order, but otherwise we sort the field to ensure61  # consistent ordering.62  field_items = fields.items()63  if not isinstance(fields, OrderedDict):64    field_items = sorted(field_items)65 66  # Use a consistent file name that is unlikely to conflict with any imported67  # proto files.68  fields_hash = hashlib.sha1()69  for f_name, f_type in field_items:70    fields_hash.update(f_name.encode('utf-8'))71    fields_hash.update(str(f_type).encode('utf-8'))72  proto_file_name = fields_hash.hexdigest() + '.proto'73 74  # If the proto is anonymous, use the same hash to name it.75  if full_name is None:76    full_name = ('net.proto2.python.public.proto_builder.AnonymousProto_' +77                 fields_hash.hexdigest())78    try:79      proto_cls = _GetMessageFromFactory(pool_instance, full_name)80      return proto_cls81    except KeyError:82      # The factory's DescriptorPool doesn't know about this class yet.83      pass84 85  # This is the first time we see this proto: add a new descriptor to the pool.86  pool_instance.Add(87      _MakeFileDescriptorProto(proto_file_name, full_name, field_items))88  return _GetMessageFromFactory(pool_instance, full_name)89 90 91def _MakeFileDescriptorProto(proto_file_name, full_name, field_items):92  """Populate FileDescriptorProto for MessageFactory's DescriptorPool."""93  package, name = full_name.rsplit('.', 1)94  file_proto = descriptor_pb2.FileDescriptorProto()95  file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name)96  file_proto.package = package97  desc_proto = file_proto.message_type.add()98  desc_proto.name = name99  for f_number, (f_name, f_type) in enumerate(field_items, 1):100    field_proto = desc_proto.field.add()101    field_proto.name = f_name102    # # If the number falls in the reserved range, reassign it to the correct103    # # number after the range.104    if f_number >= descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER:105      f_number += (106          descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER -107          descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER + 1)108    field_proto.number = f_number109    field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL110    field_proto.type = f_type111  return file_proto112 
codekingpro/portable-devtools · Team Ai