# Copyright 2021 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Definition of proto_common module.
"""

load(":common/proto/proto_semantics.bzl", "semantics")

def _create_proto_compile_action(
        ctx,
        proto_info,
        proto_compiler,
        progress_message,
        outputs,
        additional_args = [],
        plugins = [],
        mnemonic = "GenProto",
        strict_imports = False,
        additional_inputs = depset()):
    """Creates proto compile action for compiling *.proto files to language specific sources.

    It uses proto configuration fragment to access protoc_opts and strict_proto_deps flags.

    Args:
      ctx: The rule context, used to create the action and to obtain label.
      proto_info: The 'ProtoInfo' provider of the proto_library target this proto compiler invocation is for.
      proto_compiler: The proto compiler executable.
      progress_message: The progress message to set on the action.
      outputs: The output files generated by the proto compiler.
      additional_args: Additional arguments to add to the action.
        Accepts a list containing: a string, or pair of value and format string.
      plugins: Additional plugin executables used by proto compiler.
      mnemonic: The mnemonic to set on the action.
      strict_imports: Whether to check for strict imports.
      additional_inputs: Additional inputs to add to the action.
    """

    args = ctx.actions.args()
    args.use_param_file(param_file_arg = "@%s")
    args.set_param_file_format("multiline")

    args.add_all(proto_info.transitive_proto_path, map_each = _proto_path_flag)
    # Example: `--proto_path=--proto_path=bazel-bin/target/third_party/pkg/_virtual_imports/subpkg`

    for arg in additional_args:
        if type(arg) == type(("", "")):
            args.add(arg[0], format = arg[1])
        else:
            args.add(arg)

    args.add_all(ctx.fragments.proto.protoc_opts())

    # Include maps
    # For each import, include both the import as well as the import relativized against its
    # protoSourceRoot. This ensures that protos can reference either the full path or the short
    # path when including other protos.
    args.add_all(proto_info.transitive_proto_sources(), map_each = _Iimport_path_equals_fullpath)
    # Example: `-Ia.proto=bazel-bin/target/third_party/pkg/_virtual_imports/subpkg/a.proto`

    strict_deps_mode = ctx.fragments.proto.strict_proto_deps()
    strict_deps = strict_deps_mode != "OFF" and strict_deps_mode != "DEFAULT"
    if strict_deps:
        strict_importable_sources = proto_info.strict_importable_sources()
        if strict_importable_sources:
            args.add_joined("--direct_dependencies", strict_importable_sources, map_each = _get_import_path, join_with = ":")
            # Example: `--direct_dependencies a.proto:b.proto`

        else:
            # The proto compiler requires an empty list to turn on strict deps checking
            args.add("--direct_dependencies=")

        # Set `-direct_dependencies_violation_msg=`
        args.add(ctx.label, format = semantics.STRICT_DEPS_FLAG_TEMPLATE)

    if strict_imports:
        if not proto_info.public_import_sources():
            # This line is necessary to trigger the check.
            args.add("--allowed_public_imports=")
        else:
            args.add_all("--allowed_public_imports", map_each = _get_import_path, join_with = ":")

    args.add_all(proto_info.direct_sources)

    ctx.actions.run(
        mnemonic = mnemonic,
        progress_message = progress_message,
        executable = proto_compiler,
        arguments = [args],
        inputs = depset(transitive = [proto_info.transitive_sources, additional_inputs]),
        outputs = outputs,
        tools = plugins,
    )

def _proto_path_flag(path):
    if path == ".":
        return None
    return "--proto_path=%s" % path

def _get_import_path(proto_source):
    return proto_source.import_path()

def _Iimport_path_equals_fullpath(proto_source):
    return "-I%s=%s" % (proto_source.import_path(), proto_source.source_file().path)

proto_common = struct(
    create_proto_compile_action = _create_proto_compile_action,
)
