# Copyright (c) 2009-2021, Google LLC
# All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""An implementation of py_proto_library().

We have to implement this ourselves because there is currently no reasonable
py_proto_library() rule available for Bazel.

Our py_proto_library() is similar to how a real py_proto_library() should work.
But it hasn't been deeply tested or reviewed, and upb should not be in the
business of vending py_proto_library(), so we keep it private to upb.
"""

load("@bazel_skylib//lib:paths.bzl", "paths")
load("@rules_python//python:py_info.bzl", "PyInfo")
load("//bazel/common:proto_info.bzl", "ProtoInfo")

# Generic support code #########################################################

def _get_real_short_path(file):
    # For some reason, files from other archives have short paths that look like:
    #   ../com_google_protobuf/google/protobuf/descriptor.proto
    short_path = file.short_path
    if short_path.startswith("../"):
        second_slash = short_path.index("/", 3)
        short_path = short_path[second_slash + 1:]

    # Sometimes it has another few prefixes like:
    #   _virtual_imports/any_proto/google/protobuf/any.proto
    #   benchmarks/_virtual_imports/100_msgs_proto/benchmarks/100_msgs.proto
    # We want just google/protobuf/any.proto.
    virtual_imports = "_virtual_imports/"
    if virtual_imports in short_path:
        short_path = short_path.split(virtual_imports)[1].split("/", 1)[1]
    return short_path

def _get_real_root(ctx, file):
    real_short_path = _get_real_short_path(file)
    root = file.path[:-len(real_short_path) - 1]

    if ctx.rule.attr.strip_import_prefix:
        root = paths.join(root, ctx.rule.attr.strip_import_prefix[1:])

    return root

def _generate_output_file(ctx, src, extension):
    package = ctx.label.package

    strip_import_prefix = ctx.rule.attr.strip_import_prefix
    if strip_import_prefix and strip_import_prefix != "/":
        if not package.startswith(strip_import_prefix[1:]):
            fail("%s does not begin with prefix %s" % (package, strip_import_prefix))
        package = package[len(strip_import_prefix):]

    real_short_path = _get_real_short_path(src)
    real_short_path = paths.relativize(real_short_path, package)
    output_filename = paths.replace_extension(real_short_path, extension)
    ret = ctx.actions.declare_file(output_filename)
    return ret

# py_proto_library() ###########################################################

def _py_proto_library_rule_impl(ctx):
    # A real py_proto_library() should enforce this constraint.
    # We don't bother for now, since it saves us some effort not to.
    #
    # if len(ctx.attr.deps) != 1:
    #     fail("only one deps dependency allowed.")

    files = []
    for dep in ctx.attr.deps:
        files += dep[PyInfo].transitive_sources.to_list()
    return [
        DefaultInfo(files = depset(direct = files)),
    ]

def _py_proto_library_aspect_impl(target, ctx):
    proto_info = target[ProtoInfo]
    proto_sources = proto_info.direct_sources
    srcs = [_generate_output_file(ctx, name, "_pb2.py") for name in proto_sources]
    transitive_sets = proto_info.transitive_descriptor_sets.to_list()
    ctx.actions.run(
        inputs = depset(
            direct = [proto_info.direct_descriptor_set],
            transitive = [proto_info.transitive_descriptor_sets],
        ),
        outputs = srcs,
        executable = ctx.executable._protoc,
        arguments = [
                        "--python_out=" + _get_real_root(ctx, srcs[0]),
                        "--descriptor_set_in=" + ctx.configuration.host_path_separator.join([f.path for f in transitive_sets]),
                    ] +
                    [_get_real_short_path(file) for file in proto_sources],
        progress_message = "Generating Python protos for :" + ctx.label.name,
    )
    outs_depset = depset(srcs)
    return [
        PyInfo(transitive_sources = outs_depset),
    ]

_py_proto_library_aspect = aspect(
    attrs = {
        "_protoc": attr.label(
            executable = True,
            cfg = "exec",
            default = "//:protoc",
        ),
    },
    implementation = _py_proto_library_aspect_impl,
    provides = [
        PyInfo,
    ],
    attr_aspects = ["deps"],
)

py_proto_library = rule(
    implementation = _py_proto_library_rule_impl,
    attrs = {
        "deps": attr.label_list(
            aspects = [_py_proto_library_aspect],
            allow_rules = ["proto_library"],
            providers = [ProtoInfo],
        ),
    },
)
