@@ -115,6 +115,16 @@ def _Deprecated(name):
115115_internal_create_key = object ()
116116
117117
118+ def _IsDescriptorBootstrapProto (file ):
119+ """Checks if the file descriptor corresponds to our bootstrapped descriptor.proto"""
120+ if file is None :
121+ return False
122+ return (
123+ file .name == 'net/proto2/proto/descriptor.proto'
124+ or file .name == 'google/protobuf/descriptor.proto'
125+ )
126+
127+
118128class DescriptorBase (metaclass = DescriptorMetaclass ):
119129
120130 """Descriptors base class.
@@ -123,29 +133,35 @@ class DescriptorBase(metaclass=DescriptorMetaclass):
123133 related functionality.
124134
125135 Attributes:
126- has_options: True if the descriptor has non-default options. Usually it
127- is not necessary to read this -- just call GetOptions() which will
128- happily return the default instance. However, it's sometimes useful
129- for efficiency, and also useful inside the protobuf implementation to
130- avoid some bootstrapping issues.
136+ has_options: True if the descriptor has non-default options. Usually it is
137+ not necessary to read this -- just call GetOptions() which will happily
138+ return the default instance. However, it's sometimes useful for
139+ efficiency, and also useful inside the protobuf implementation to avoid
140+ some bootstrapping issues.
141+ file (FileDescriptor): Reference to file info.
131142 """
132143
133144 if _USE_C_DESCRIPTORS :
134145 # The class, or tuple of classes, that are considered as "virtual
135146 # subclasses" of this descriptor class.
136147 _C_DESCRIPTOR_CLASS = ()
137148
138- def __init__ (self , options , serialized_options , options_class_name ):
149+ def __init__ (self , file , options , serialized_options , options_class_name ):
139150 """Initialize the descriptor given its options message and the name of the
140151 class of the options message. The name of the class is required in case
141152 the options message is None and has to be created.
142153 """
154+ self .file = file
143155 self ._options = options
144156 self ._options_class_name = options_class_name
145- self ._serialized_options = serialized_options
157+ self ._serialized_options = (
158+ serialized_options if not _IsDescriptorBootstrapProto (file ) else None
159+ )
146160
147161 # Does this descriptor have non-default options?
148- self .has_options = (options is not None ) or (serialized_options is not None )
162+ self .has_options = (self ._options is not None ) or (
163+ self ._serialized_options is not None
164+ )
149165
150166 def _SetOptions (self , options , options_class_name ):
151167 """Sets the descriptor's options
@@ -195,14 +211,12 @@ def __init__(self, options, options_class_name, name, full_name,
195211 """Constructor.
196212
197213 Args:
198- options: Protocol message options or None
199- to use default message options.
214+ options: Protocol message options or None to use default message options.
200215 options_class_name (str): The class name of the above options.
201216 name (str): Name of this protocol message type.
202- full_name (str): Fully-qualified name of this protocol message type,
203- which will include protocol "package" name and the name of any
204- enclosing types.
205- file (FileDescriptor): Reference to file info.
217+ full_name (str): Fully-qualified name of this protocol message type, which
218+ will include protocol "package" name and the name of any enclosing
219+ types.
206220 containing_type: if provided, this is a nested descriptor, with this
207221 descriptor as parent, otherwise None.
208222 serialized_start: The start index (inclusive) in block in the
@@ -212,13 +226,13 @@ def __init__(self, options, options_class_name, name, full_name,
212226 serialized_options: Protocol message serialized options or None.
213227 """
214228 super (_NestedDescriptorBase , self ).__init__ (
215- options , serialized_options , options_class_name )
229+ file , options , serialized_options , options_class_name
230+ )
216231
217232 self .name = name
218233 # TODO(falk): Add function to calculate full_name instead of having it in
219234 # memory?
220235 self .full_name = full_name
221- self .file = file
222236 self .containing_type = containing_type
223237
224238 self ._serialized_start = serialized_start
@@ -581,10 +595,10 @@ def __init__(self, name, full_name, index, number, type, cpp_type, label,
581595 _Deprecated ('FieldDescriptor' )
582596
583597 super (FieldDescriptor , self ).__init__ (
584- options , serialized_options , 'FieldOptions' )
598+ file , options , serialized_options , 'FieldOptions'
599+ )
585600 self .name = name
586601 self .full_name = full_name
587- self .file = file
588602 self ._camelcase_name = None
589603 if json_name is None :
590604 self .json_name = _ToJsonName (name )
@@ -732,6 +746,7 @@ def __init__(self, name, full_name, filename, values,
732746
733747 self .values = values
734748 for value in self .values :
749+ value .file = file
735750 value .type = self
736751 self .values_by_name = dict ((v .name , v ) for v in values )
737752 # Values are reversed to ensure that the first alias is retained.
@@ -808,7 +823,11 @@ def __init__(self, name, index, number,
808823 _Deprecated ('EnumValueDescriptor' )
809824
810825 super (EnumValueDescriptor , self ).__init__ (
811- options , serialized_options , 'EnumValueOptions' )
826+ type .file if type else None ,
827+ options ,
828+ serialized_options ,
829+ 'EnumValueOptions' ,
830+ )
812831 self .name = name
813832 self .index = index
814833 self .number = number
@@ -847,7 +866,11 @@ def __init__(
847866 _Deprecated ('OneofDescriptor' )
848867
849868 super (OneofDescriptor , self ).__init__ (
850- options , serialized_options , 'OneofOptions' )
869+ containing_type .file if containing_type else None ,
870+ options ,
871+ serialized_options ,
872+ 'OneofOptions' ,
873+ )
851874 self .name = name
852875 self .full_name = full_name
853876 self .index = index
@@ -907,6 +930,7 @@ def __init__(self, name, full_name, index, methods, options=None,
907930 self .methods_by_name = dict ((m .name , m ) for m in methods )
908931 # Set the containing service for each method in this service.
909932 for method in self .methods :
933+ method .file = self .file
910934 method .containing_service = self
911935
912936 def FindMethodByName (self , name ):
@@ -992,7 +1016,11 @@ def __init__(self,
9921016 _Deprecated ('MethodDescriptor' )
9931017
9941018 super (MethodDescriptor , self ).__init__ (
995- options , serialized_options , 'MethodOptions' )
1019+ containing_service .file if containing_service else None ,
1020+ options ,
1021+ serialized_options ,
1022+ 'MethodOptions' ,
1023+ )
9961024 self .name = name
9971025 self .full_name = full_name
9981026 self .index = index
@@ -1076,7 +1104,8 @@ def __init__(self, name, package, options=None,
10761104 _Deprecated ('FileDescriptor' )
10771105
10781106 super (FileDescriptor , self ).__init__ (
1079- options , serialized_options , 'FileOptions' )
1107+ None , options , serialized_options , 'FileOptions'
1108+ )
10801109
10811110 if pool is None :
10821111 from google .protobuf import descriptor_pool
0 commit comments