示例#1
0
def VersionUpgradeXform(n, envoy_internal_shadow, file_proto, params):
    """Transform a FileDescriptorProto from vN[alpha\d] to v(N+1).

  Args:
    n: version N to upgrade from.
    envoy_internal_shadow: generate a shadow for Envoy internal use containing deprecated fields.
    file_proto: vN[alpha\d] FileDescriptorProto message.
    params: plugin parameters.

  Returns:
    v(N+1) FileDescriptorProto message.
  """
    # Load type database.
    if params['type_db_path']:
        utils.LoadTypeDb(params['type_db_path'])
    typedb = utils.GetTypeDb()
    # If this isn't a proto in an upgraded package, return None.
    if file_proto.name not in typedb.next_version_protos or not typedb.next_version_protos[
            file_proto.name]:
        return None
    # Otherwise, this .proto needs upgrading, do it.
    freeze = 'extra_args' in params and params['extra_args'] == 'freeze'
    existing_pkg_version_status = file_proto.options.Extensions[
        status_pb2.file_status].package_version_status
    # Normally, we are generating the NEXT_MAJOR_VERSION_CANDIDATE. However, if
    # freezing and previously this was the active major version, the migrated
    # version is now the ACTIVE version.
    if freeze and existing_pkg_version_status == status_pb2.ACTIVE:
        package_version_status = status_pb2.ACTIVE
    else:
        package_version_status = status_pb2.NEXT_MAJOR_VERSION_CANDIDATE
    return traverse.TraverseFile(
        file_proto,
        UpgradeVisitor(n, typedb, envoy_internal_shadow,
                       package_version_status))
示例#2
0
def V3MigrationXform(file_proto):
  """Transform a FileDescriptorProto from v2[alpha\d] to v3alpha.

  Args:
    file_proto: v2[alpha\d] FileDescriptorProto message.

  Returns:
    v3 FileDescriptorProto message.
  """
  # Load type database.
  typedb = utils.LoadTypeDb()
  # If this isn't a proto in an upgraded package, return None.
  if file_proto.package not in typedb.next_version_packages or not typedb.next_version_packages[
      file_proto.package]:
    return None
  # Otherwise, this .proto needs upgrading, do it.
  return traverse.TraverseFile(file_proto, UpgradeVisitor(typedb))
示例#3
0
            type_context.ExtendOneof(oneof_index, field.name))
        fields += '%soneof %s {\n%s%s' % (oneof_leading_comment, oneof_proto.name,
                                          oneof_trailing_comment, FormatOptions(
                                              oneof_proto.options))
      fields += FormatBlock(FormatField(type_context.ExtendField(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 VisitFile(self, file_proto, type_context, services, msgs, enums):
    empty_file = len(services) == 0 and len(enums) == 0 and len(msgs) == 0
    header = FormatHeaderFromFile(type_context.source_code_info, file_proto, empty_file)
    formatted_services = FormatBlock('\n'.join(services))
    formatted_enums = FormatBlock('\n'.join(enums))
    formatted_msgs = FormatBlock('\n'.join(msgs))
    return ClangFormat(header + formatted_services + formatted_enums + formatted_msgs)


if __name__ == '__main__':
  proto_desc_path = sys.argv[1]
  file_proto = descriptor_pb2.FileDescriptorProto()
  input_text = pathlib.Path(proto_desc_path).read_text()
  if not input_text:
    sys.exit(0)
  text_format.Merge(input_text, file_proto)
  dst_path = pathlib.Path(sys.argv[2])
  utils.LoadTypeDb(sys.argv[3])
  dst_path.write_bytes(traverse.TraverseFile(file_proto, ProtoFormatVisitor()))
示例#4
0
def FormatHeaderFromFile(source_code_info, file_proto):
    """Format proto header.

  Args:
    source_code_info: SourceCodeInfo object.
    file_proto: FileDescriptorProto for file.

  Returns:
    Formatted proto header as a string.
  """
    # Load the type database.
    typedb = utils.LoadTypeDb()
    # Figure out type dependencies in this .proto.
    types = Types()
    text_format.Merge(
        traverse.TraverseFile(file_proto,
                              type_whisperer.TypeWhispererVisitor()), types)
    type_dependencies = sum(
        [list(t.type_dependencies) for t in types.types.values()], [])
    for service in file_proto.service:
        for m in service.method:
            type_dependencies.extend([m.input_type[1:], m.output_type[1:]])
    # Determine the envoy/ import paths from type deps.
    envoy_proto_paths = set(typedb.types[t].proto_path
                            for t in type_dependencies
                            if t.startswith('envoy.')
                            and typedb.types[t].proto_path != file_proto.name)

    def CamelCase(s):
        return ''.join(t.capitalize() for t in re.split('[\._]', s))

    package_line = 'package %s;\n' % file_proto.package
    file_block = '\n'.join(['syntax = "proto3";\n', package_line])

    options = [
        'option java_outer_classname = "%s";' %
        CamelCase(os.path.basename(file_proto.name)),
        'option java_multiple_files = true;',
        'option java_package = "io.envoyproxy.%s";' % file_proto.package,
    ]
    # This is a workaround for C#/Ruby namespace conflicts between packages and
    # objects, see https://github.com/envoyproxy/envoy/pull/3854.
    # TODO(htuch): remove once v3 fixes this naming issue in
    # https://github.com/envoyproxy/envoy/issues/8120.
    if file_proto.package in ['envoy.api.v2.listener', 'envoy.api.v2.cluster']:
        qualified_package = '.'.join(
            s.capitalize() for s in file_proto.package.split('.')) + 'NS'
        options += [
            'option csharp_namespace = "%s";' % qualified_package,
            'option ruby_package = "%s";' % qualified_package,
        ]
    if file_proto.service:
        options += ['option java_generic_services = true;']
    options_block = FormatBlock('\n'.join(options))

    envoy_imports = list(envoy_proto_paths)
    google_imports = []
    infra_imports = []
    misc_imports = []

    for d in file_proto.dependency:
        if d.startswith('envoy/'):
            # We ignore existing envoy/ imports, since these are computed explicitly
            # from type_dependencies.
            pass
        elif d.startswith('google/'):
            google_imports.append(d)
        elif d.startswith('validate/'):
            infra_imports.append(d)
        else:
            misc_imports.append(d)

    def FormatImportBlock(xs):
        if not xs:
            return ''
        return FormatBlock('\n'.join(sorted('import "%s";' % x for x in xs)))

    import_block = '\n'.join(
        map(FormatImportBlock,
            [envoy_imports, google_imports, misc_imports, infra_imports]))
    comment_block = FormatComments(source_code_info.file_level_comments)

    return ''.join(
        map(FormatBlock,
            [file_block, options_block, import_block, comment_block]))
示例#5
0
def ParameterCallback(parameter):
  params = dict(param.split('=') for param in parameter.split(','))
  if params['type_db_path']:
    utils.LoadTypeDb(params['type_db_path'])
示例#6
0
 def __init__(self, active_or_frozen, params):
     if params['type_db_path']:
         utils.LoadTypeDb(params['type_db_path'])
     self._freeze = 'extra_args' in params and params[
         'extra_args'] == 'freeze'
     self._active_or_frozen = active_or_frozen