protobuf/python/google/protobuf/proto_builder.py
Go to the documentation of this file.
1 # Protocol Buffers - Google's data interchange format
2 # Copyright 2008 Google Inc. All rights reserved.
3 # https://developers.google.com/protocol-buffers/
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 """Dynamic Protobuf class creator."""
32 
33 from collections import OrderedDict
34 import hashlib
35 import os
36 
37 from google.protobuf import descriptor_pb2
38 from google.protobuf import descriptor
39 from google.protobuf import message_factory
40 
41 
42 def _GetMessageFromFactory(factory, full_name):
43  """Get a proto class from the MessageFactory by name.
44 
45  Args:
46  factory: a MessageFactory instance.
47  full_name: str, the fully qualified name of the proto type.
48  Returns:
49  A class, for the type identified by full_name.
50  Raises:
51  KeyError, if the proto is not found in the factory's descriptor pool.
52  """
53  proto_descriptor = factory.pool.FindMessageTypeByName(full_name)
54  proto_cls = factory.GetPrototype(proto_descriptor)
55  return proto_cls
56 
57 
58 def MakeSimpleProtoClass(fields, full_name=None, pool=None):
59  """Create a Protobuf class whose fields are basic types.
60 
61  Note: this doesn't validate field names!
62 
63  Args:
64  fields: dict of {name: field_type} mappings for each field in the proto. If
65  this is an OrderedDict the order will be maintained, otherwise the
66  fields will be sorted by name.
67  full_name: optional str, the fully-qualified name of the proto type.
68  pool: optional DescriptorPool instance.
69  Returns:
70  a class, the new protobuf class with a FileDescriptor.
71  """
72  factory = message_factory.MessageFactory(pool=pool)
73 
74  if full_name is not None:
75  try:
76  proto_cls = _GetMessageFromFactory(factory, full_name)
77  return proto_cls
78  except KeyError:
79  # The factory's DescriptorPool doesn't know about this class yet.
80  pass
81 
82  # Get a list of (name, field_type) tuples from the fields dict. If fields was
83  # an OrderedDict we keep the order, but otherwise we sort the field to ensure
84  # consistent ordering.
85  field_items = fields.items()
86  if not isinstance(fields, OrderedDict):
87  field_items = sorted(field_items)
88 
89  # Use a consistent file name that is unlikely to conflict with any imported
90  # proto files.
91  fields_hash = hashlib.sha1()
92  for f_name, f_type in field_items:
93  fields_hash.update(f_name.encode('utf-8'))
94  fields_hash.update(str(f_type).encode('utf-8'))
95  proto_file_name = fields_hash.hexdigest() + '.proto'
96 
97  # If the proto is anonymous, use the same hash to name it.
98  if full_name is None:
99  full_name = ('net.proto2.python.public.proto_builder.AnonymousProto_' +
100  fields_hash.hexdigest())
101  try:
102  proto_cls = _GetMessageFromFactory(factory, full_name)
103  return proto_cls
104  except KeyError:
105  # The factory's DescriptorPool doesn't know about this class yet.
106  pass
107 
108  # This is the first time we see this proto: add a new descriptor to the pool.
109  factory.pool.Add(
110  _MakeFileDescriptorProto(proto_file_name, full_name, field_items))
111  return _GetMessageFromFactory(factory, full_name)
112 
113 
114 def _MakeFileDescriptorProto(proto_file_name, full_name, field_items):
115  """Populate FileDescriptorProto for MessageFactory's DescriptorPool."""
116  package, name = full_name.rsplit('.', 1)
117  file_proto = descriptor_pb2.FileDescriptorProto()
118  file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name)
119  file_proto.package = package
120  desc_proto = file_proto.message_type.add()
121  desc_proto.name = name
122  for f_number, (f_name, f_type) in enumerate(field_items, 1):
123  field_proto = desc_proto.field.add()
124  field_proto.name = f_name
125  # # If the number falls in the reserved range, reassign it to the correct
126  # # number after the range.
127  if f_number >= descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER:
128  f_number += (
129  descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER -
130  descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER + 1)
131  field_proto.number = f_number
132  field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
133  field_proto.type = f_type
134  return file_proto
xds_interop_client.str
str
Definition: xds_interop_client.py:487
google::protobuf.proto_builder._MakeFileDescriptorProto
def _MakeFileDescriptorProto(proto_file_name, full_name, field_items)
Definition: bloaty/third_party/protobuf/python/google/protobuf/proto_builder.py:116
google::protobuf.proto_builder._GetMessageFromFactory
def _GetMessageFromFactory(factory, full_name)
Definition: bloaty/third_party/protobuf/python/google/protobuf/proto_builder.py:44
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
grpc._common.encode
def encode(s)
Definition: grpc/_common.py:68
google::protobuf.proto_builder.MakeSimpleProtoClass
def MakeSimpleProtoClass(fields, full_name=None, pool=None)
Definition: bloaty/third_party/protobuf/python/google/protobuf/proto_builder.py:60


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:47