# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# TODO: Fix the visibility on the static_library.
# gnlint: disable=GnLintVisibilityFlags

# Compile protocol buffers.
#
# Paramaeters:
#   proto_in_dir
#       Input directory.
#   proto_out_dir
#       Output directory.
#   proto_lib_dirs (optional)
#       Directories to search for protos a proto file depends on.
#       proto_in_dir and "${sysroot}/usr/share/proto" are added by default.
#   sources
#       The proto file paths.
#   configs (optional)
#       Configs applied to the generated library.
#   deps (optional)
#       Deps applied to the generated library.
#   gen_python (optional)
#       If true, generates Python binding.
#   gen_go_grpc (optional)
#       If true, generates Go GRPC.
#   gen_grpc (optional)
#       If true, generates C++ GRPC.
#   gen_grpc_gmock (optional)
#       If true, along with gen_grpc, generates C++ GRPC gmock objects as well.
#   use_pic (optional)
#       If true, generates a position independent code instead of position independent executable.
#   standalone
#       If true, generates a library that can be referred from other packages.
#       Otherwise it generates a thin archive assuming it's used inside the same package only.
template("proto_library") {
  action_name = "${target_name}_gen"
  action_foreach(action_name) {
    visibility = [ ":*" ]

    forward_variables_from(invoker,
                           [
                             "proto_in_dir",
                             "proto_out_dir",
                             "gen_python",
                             "gen_go_grpc",
                             "gen_grpc",
                             "gen_grpc_gmock",

                             # Sources might be generated by actions in deps,
                             # which must be explicitly specified.
                             "deps",
                             "public_deps",
                             "sources",
                           ])

    cc_dir = "${root_gen_dir}/${proto_out_dir}"
    proto_in_dir = rebase_path(proto_in_dir)
    proto_out_dir = rebase_path(proto_out_dir)

    proto_lib_dirs = [
      proto_in_dir,
      "${sysroot}/usr/share/proto",
    ]
    if (defined(invoker.proto_lib_dirs)) {
      proto_lib_dirs += rebase_path(invoker.proto_lib_dirs)
    }

    if (!defined(gen_python)) {
      gen_python = false
    }
    if (!defined(gen_go_grpc)) {
      gen_go_grpc = false
    }
    if (!defined(gen_grpc)) {
      gen_grpc = false
    }
    if (gen_grpc && !defined(gen_grpc_gmock)) {
      gen_grpc_gmock = false
    }

    script = "//common-mk/file_generator_wrapper.py"
    args = [ "protoc" ]
    foreach(x, proto_lib_dirs) {
      args += [
        "--proto_path",
        x,
      ]
    }
    args += [ "${proto_in_dir}/{{source_name_part}}.proto" ]
    outputs = []
    if (gen_python) {
      python_dir = "${root_gen_dir}/${proto_out_dir}/py"
      args += [
        "--python_out",
        "${python_dir}",
      ]
      outputs += [ "${python_dir}/{{source_name_part}}_pb.py" ]
    }
    if (gen_grpc) {
      if (gen_grpc_gmock) {
        args += [ "--grpc_out=generate_mock_code=true:${cc_dir}" ]
        outputs += [ "${cc_dir}/{{source_name_part}}_mock.grpc.pb.h" ]
      } else {
        args += [ "--grpc_out=${cc_dir}" ]
      }
      grpc_cpp_plugin = "/usr/bin/grpc_cpp_plugin"
      args += [
        "--plugin=protoc-gen-grpc=${grpc_cpp_plugin}",
        "--cpp_out=${cc_dir}",
      ]
      outputs += [
        "${cc_dir}/{{source_name_part}}.grpc.pb.cc",
        "${cc_dir}/{{source_name_part}}.grpc.pb.h",
        "${cc_dir}/{{source_name_part}}.pb.cc",
        "${cc_dir}/{{source_name_part}}.pb.h",
      ]
    }
    if (gen_go_grpc) {
      args += [ "--go_out=plugins=grpc:${go_dir}" ]
      outputs += [ "${go_dir}/{{source_name_part}}.pb.go" ]
    }
    if (!gen_grpc && !gen_go_grpc && !gen_python) {
      args += [
        "--cpp_out",
        "${cc_dir}",
      ]
      outputs += [
        "${cc_dir}/{{source_name_part}}.pb.cc",
        "${cc_dir}/{{source_name_part}}.pb.h",
      ]
    }
  }

  static_library(target_name) {
    forward_variables_from(invoker,
                           [
                             "all_dependent_configs",
                             "defines",
                             "public_configs",
                             "public_deps",
                             "visibility",
                           ])
    if (defined(invoker.configs)) {
      configs += invoker.configs
    }
    if (defined(invoker.use_pic) && invoker.use_pic) {
      configs -= [ "//common-mk:pie" ]
      configs += [ "//common-mk:pic" ]
    }
    if (defined(invoker.standalone) && invoker.standalone) {
      configs -= [ "//common-mk:use_thin_archive" ]
      configs += [
        "//common-mk:nouse_thin_archive",
        "//common-mk:visibility_default",
      ]
    }
    sources = get_target_outputs(":${action_name}")
    deps = [
      ":${action_name}",
    ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
  }
}

# Compile protocol buffers to Go.
#
# Parameters:
#   proto_in_dir
#       Input directory.
#   proto_out_dir
#       Output directory. Relative to gen directory.
#   sources
#       The proto file paths.
template("goproto_library") {
  action(target_name) {
    forward_variables_from(invoker,
                           [
                             "proto_out_dir",
                             "sources",
                           ])

    # For go, it is necessary to generate the code in one command line,
    # otherwise file descriptor var name will conflict.
    # cf) https://github.com/golang/protobuf/issues/109

    proto_in_dir = rebase_path(invoker.proto_in_dir)

    # Build protoc command line to run.
    script = "//common-mk/file_generator_wrapper.py"
    args = [
      "protoc",
      "--proto_path",
      proto_in_dir,
      "--proto_path",
      "${sysroot}/usr/share/proto",
      "--go_out",
      "${root_gen_dir}/${proto_out_dir}",
    ]
    foreach(source, sources) {
      args += [ rebase_path(source) ]
    }

    # Output dependency.
    outputs = []
    foreach(source, invoker.sources) {
      name = get_path_info(source, "name")
      outputs += [ "${root_gen_dir}/${proto_out_dir}/${name}.pb.go" ]
    }
  }
}
