def MergeActiveShadowFile(active_file_proto, shadow_file_proto): target_file_proto = copy.deepcopy(active_file_proto) source_code_info = api_type_context.SourceCodeInfo( target_file_proto.name, target_file_proto.source_code_info) package_type_context = api_type_context.TypeContext( source_code_info, target_file_proto.package) # Visit message types del target_file_proto.message_type[:] shadow_msgs = {msg.name: msg for msg in shadow_file_proto.message_type} for index, msg in enumerate(active_file_proto.message_type): MergeActiveShadowMessage( package_type_context.ExtendMessage(index, msg.name, msg.options.deprecated), msg, shadow_msgs.get(msg.name), target_file_proto.message_type.add()) # Visit enum types del target_file_proto.enum_type[:] shadow_enums = {msg.name: msg for msg in shadow_file_proto.enum_type} for enum in active_file_proto.enum_type: MergeActiveShadowEnum(enum, shadow_enums.get(enum.name), target_file_proto.enum_type.add()) # Ensure target has any deprecated message types in case they are needed. active_msg_names = set( [msg.name for msg in active_file_proto.message_type]) for msg in shadow_file_proto.message_type: if msg.name not in active_msg_names: target_file_proto.message_type.add().MergeFrom(msg) return target_file_proto
def TraverseFile(file_proto, visitor): """Traverse a proto file definition. Args: file_proto: FileDescriptorProto for file. visitor: visitor.Visitor defining the business logic of the plugin. Returns: Plugin specific output. """ source_code_info = type_context.SourceCodeInfo(file_proto.name, file_proto.source_code_info) package_type_context = type_context.TypeContext(source_code_info, file_proto.package) msgs = [ TraverseMessage(package_type_context.ExtendMessage(index, msg.name), msg, visitor) for index, msg in enumerate(file_proto.message_type) ] enums = [ TraverseEnum(package_type_context.ExtendEnum(index, enum.name), enum, visitor) for index, enum in enumerate(file_proto.enum_type) ] return visitor.VisitFile(file_proto, package_type_context, msgs, enums)
def traverse_file(file_proto, visitor): """Traverse a proto file definition. Args: file_proto: FileDescriptorProto for file. visitor: visitor.Visitor defining the business logic of the plugin. Returns: Plugin specific output. """ source_code_info = type_context.SourceCodeInfo(file_proto.name, file_proto.source_code_info) package_type_context = type_context.TypeContext(source_code_info, file_proto.package) services = [ traverse_service( package_type_context.extend_service(index, service.name), service, visitor) for index, service in enumerate(file_proto.service) ] msgs = [ traverse_message( package_type_context.extend_message(index, msg.name, msg.options.deprecated), msg, visitor) for index, msg in enumerate(file_proto.message_type) ] enums = [ traverse_enum( package_type_context.extend_enum(index, enum.name, enum.options.deprecated), enum, visitor) for index, enum in enumerate(file_proto.enum_type) ] return visitor.visit_file(file_proto, package_type_context, services, msgs, enums)
def testmerge_active_shadow_message_comments(self): """merge_active_shadow_message preserves comment field correspondence.""" active_pb_text = """ field { number: 9 name: "oneof_1_0" oneof_index: 0 } field { number: 1 name: "simple_field_0" } field { number: 0 name: "oneof_2_0" oneof_index: 2 } field { number: 8 name: "oneof_2_1" oneof_index: 2 } field { number: 3 name: "oneof_0_0" oneof_index: 1 } field { number: 4 name: "newbie" } field { number: 7 name: "oneof_3_0" oneof_index: 3 } reserved_name: "missing_oneof_field_0" reserved_name: "missing_oneof_field_1" reserved_name: "missing_oneof_field_2" oneof_decl { name: "oneof_0" } oneof_decl { name: "oneof_1" } oneof_decl { name: "oneof_2" } oneof_decl { name: "oneof_3" } """ active_proto = descriptor_pb2.DescriptorProto() text_format.Merge(active_pb_text, active_proto) active_source_code_info_text = """ location { path: [4, 1, 2, 4] leading_comments: "field_4" } location { path: [4, 1, 2, 5] leading_comments: "field_5" } location { path: [4, 1, 2, 3] leading_comments: "field_3" } location { path: [4, 1, 2, 0] leading_comments: "field_0" } location { path: [4, 1, 2, 1] leading_comments: "field_1" } location { path: [4, 0, 2, 2] leading_comments: "ignore_0" } location { path: [4, 1, 2, 6] leading_comments: "field_6" } location { path: [4, 1, 2, 2] leading_comments: "field_2" } location { path: [3] leading_comments: "ignore_1" } """ active_source_code_info = descriptor_pb2.SourceCodeInfo() text_format.Merge(active_source_code_info_text, active_source_code_info) shadow_pb_text = """ field { number: 10 name: "hidden_envoy_deprecated_missing_oneof_field_0" oneof_index: 0 } field { number: 11 name: "hidden_envoy_deprecated_missing_oneof_field_1" oneof_index: 3 } field { number: 11 name: "hidden_envoy_deprecated_missing_oneof_field_2" oneof_index: 2 } oneof_decl { name: "oneof_0" } oneof_decl { name: "oneof_1" } oneof_decl { name: "oneof_2" } oneof_decl { name: "some_removed_oneof" } oneof_decl { name: "oneof_3" } """ shadow_proto = descriptor_pb2.DescriptorProto() text_format.Merge(shadow_pb_text, shadow_proto) target_proto = descriptor_pb2.DescriptorProto() source_code_info = api_type_context.SourceCodeInfo('fake', active_source_code_info) fake_type_context = api_type_context.TypeContext(source_code_info, 'fake_package') target_proto_dependencies = [] merge_active_shadow.merge_active_shadow_message( fake_type_context.extend_message(1, "foo", False), active_proto, shadow_proto, target_proto, target_proto_dependencies) target_pb_text = """ field { name: "oneof_1_0" number: 9 oneof_index: 0 } field { name: "hidden_envoy_deprecated_missing_oneof_field_0" number: 10 oneof_index: 0 } field { name: "simple_field_0" number: 1 } field { name: "oneof_2_0" number: 0 oneof_index: 2 } field { name: "oneof_2_1" number: 8 oneof_index: 2 } field { name: "hidden_envoy_deprecated_missing_oneof_field_2" number: 11 oneof_index: 2 } field { name: "oneof_0_0" number: 3 oneof_index: 1 } field { name: "newbie" number: 4 } field { name: "oneof_3_0" number: 7 oneof_index: 3 } field { name: "hidden_envoy_deprecated_missing_oneof_field_1" number: 11 oneof_index: 4 } oneof_decl { name: "oneof_0" } oneof_decl { name: "oneof_1" } oneof_decl { name: "oneof_2" } oneof_decl { name: "oneof_3" } oneof_decl { name: "some_removed_oneof" } """ target_source_code_info_text = """ location { path: 4 path: 1 path: 2 path: 6 leading_comments: "field_4" } location { path: 4 path: 1 path: 2 path: 7 leading_comments: "field_5" } location { path: 4 path: 1 path: 2 path: 4 leading_comments: "field_3" } location { path: 4 path: 1 path: 2 path: 0 leading_comments: "field_0" } location { path: 4 path: 1 path: 2 path: 2 leading_comments: "field_1" } location { path: 4 path: 0 path: 2 path: 2 leading_comments: "ignore_0" } location { path: 4 path: 1 path: 2 path: 8 leading_comments: "field_6" } location { path: 4 path: 1 path: 2 path: 3 leading_comments: "field_2" } location { path: 3 leading_comments: "ignore_1" } """ self.maxDiff = None self.assert_text_proto_eq(target_pb_text, str(target_proto)) self.assert_text_proto_eq(target_source_code_info_text, str(fake_type_context.source_code_info.proto))
def fake_type_context(self): fake_source_code_info = descriptor_pb2.SourceCodeInfo() source_code_info = api_type_context.SourceCodeInfo('fake', fake_source_code_info) return api_type_context.TypeContext(source_code_info, 'fake_package')