def visit_message(self, msg_proto, type_context, nested_msgs, nested_enums): # Skip messages synthesized to represent map types. if msg_proto.options.map_entry: return '' if protoxform_options.has_hide_option(msg_proto.options): return '' annotation_xforms = { annotations.NEXT_FREE_FIELD_ANNOTATION: create_next_free_field_xform(msg_proto) } leading_comment, trailing_comment = format_type_context_comments( type_context, annotation_xforms) formatted_options = format_options(msg_proto.options) formatted_enums = format_block('\n'.join(nested_enums)) formatted_msgs = format_block('\n'.join(nested_msgs)) reserved_fields = format_reserved(msg_proto) # Recover the oneof structure. This needs some extra work, since # DescriptorProto just gives use fields and a oneof_index that can allow # recovery of the original oneof placement. fields = '' oneof_index = None for index, field in enumerate(msg_proto.field): if oneof_index is not None: if not field.HasField( 'oneof_index') or field.oneof_index != oneof_index: fields += '}\n\n' oneof_index = None if oneof_index is None and field.HasField('oneof_index'): oneof_index = field.oneof_index assert (oneof_index < len(msg_proto.oneof_decl)) oneof_proto = msg_proto.oneof_decl[oneof_index] oneof_leading_comment, oneof_trailing_comment = format_type_context_comments( type_context.extend_oneof(oneof_index, field.name)) fields += '%soneof %s {\n%s%s' % ( oneof_leading_comment, oneof_proto.name, oneof_trailing_comment, format_options( oneof_proto.options)) # Verify that deprecated fields (that are not hidden and are not of frozen protos) # have a minor version annotation. self._add_deprecation_version( field, deprecation_pb2.deprecated_at_minor_version, deprecation_pb2.disallowed_by_default) fields += format_block( format_field(type_context.extend_field(index, field.name), field)) if oneof_index is not None: fields += '}\n\n' return '%smessage %s {\n%s%s%s%s%s%s\n}\n' % ( leading_comment, msg_proto.name, trailing_comment, formatted_options, formatted_enums, formatted_msgs, reserved_fields, fields)
def visit_enum(self, enum_proto, type_context): if protoxform_options.has_hide_option(enum_proto.options): return '' leading_comment, trailing_comment = format_type_context_comments(type_context) formatted_options = format_options(enum_proto.options) reserved_fields = format_reserved(enum_proto) values = [ format_enum_value(type_context.extend_field(index, value.name), value) for index, value in enumerate(enum_proto.value) ] joined_values = ('\n' if any('//' in v for v in values) else '').join(values) return '%senum %s {\n%s%s%s%s\n}\n' % (leading_comment, enum_proto.name, trailing_comment, formatted_options, reserved_fields, joined_values)
def format_enum_value(type_context, value): """Format a EnumValueDescriptorProto as a proto enum value. Args: type_context: contextual information for message/enum/field. value: EnumValueDescriptorProto. Returns: Formatted proto enum value as a string. """ if protoxform_options.has_hide_option(value.options): return '' leading_comment, trailing_comment = format_type_context_comments(type_context) formatted_annotations = format_options(value.options) return '%s%s = %d%s;\n%s' % ( leading_comment, value.name, value.number, formatted_annotations, trailing_comment)
def format_field(type_context, field): """Format FieldDescriptorProto as a proto field. Args: type_context: contextual information for message/enum/field. field: FieldDescriptor proto. Returns: Formatted proto field as a string. """ if protoxform_options.has_hide_option(field.options): return '' leading_comment, trailing_comment = format_type_context_comments(type_context) return '%s%s %s = %d%s;\n%s' % ( leading_comment, format_field_type(type_context, field), field.name, field.number, format_options(field.options), trailing_comment)
def visit_enum(self, enum_proto, type_context): if protoxform_options.has_hide_option(enum_proto.options): return '' # Verify that not hidden deprecated enum values of non-frozen protos have valid version # annotations. for v in enum_proto.value: self._add_deprecation_version( v, deprecation_pb2.deprecated_at_minor_version_enum, deprecation_pb2.disallowed_by_default_enum) leading_comment, trailing_comment = format_type_context_comments(type_context) formatted_options = format_options(enum_proto.options) reserved_fields = format_reserved(enum_proto) values = [ format_enum_value(type_context.extend_field(index, value.name), value) for index, value in enumerate(enum_proto.value) ] joined_values = ('\n' if any('//' in v for v in values) else '').join(values) return '%senum %s {\n%s%s%s%s\n}\n' % ( leading_comment, enum_proto.name, trailing_comment, formatted_options, reserved_fields, joined_values)
def _add_deprecation_version(self, field_or_evalue, deprecation_tag, disallowed_tag): """Adds a deprecation version annotation if needed to the given field or enum value. The annotation is added if all the following hold: - The field or enum value are marked as deprecated. - The proto is not frozen. - The field or enum value are not marked as hidden. - The field or enum value do not already have a version annotation. - The field or enum value name is not ENVOY_DEPRECATED_UNAVIALABLE_NAME. If a field or enum value are marked with an annotation, the _requires_deprecation_annotation_import flag is set. The function also validates that if a field or enum value already have the deprecated annotation value, then this value is a valid one ("X.Y" where X and Y are valid major, and minor versions, respectively). """ if field_or_evalue.options.deprecated and not self._frozen_proto and \ not protoxform_options.has_hide_option(field_or_evalue.options): # If the field or enum value has annotation from deprecation.proto, need to import it. self._requires_deprecation_annotation_import = ( self._requires_deprecation_annotation_import or field_or_evalue.options.HasExtension(deprecation_tag) or field_or_evalue.options.HasExtension(disallowed_tag)) if field_or_evalue.name != ENVOY_DEPRECATED_UNAVIALABLE_NAME: # If there's a deprecated version annotation, ensure it is valid. if field_or_evalue.options.HasExtension(deprecation_tag): if not api_version_utils.is_deprecated_annotation_version( field_or_evalue.options.Extensions[deprecation_tag] ): raise ProtoPrintError( 'Error while parsing "deprecated_at_minor_version_enum" annotation "%s" value for enum value %s.' % (field_or_evalue.options. Extensions[deprecation_tag], field_or_evalue.name)) else: # Add the current version as a deprecated version annotation. self._requires_deprecation_annotation_import = True field_or_evalue.options.Extensions[ deprecation_tag] = self._deprecated_annotation_version_value