# 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_grpc (optional)
#       If true, generates C++ GRPC.
#   gen_grpc_gmock (optional)
#       If true, along with gen_grpc, generates C++ GRPC gmock objects as well.
#   gen_cpp_mode (optional)
#       If defined, ignores the OPTIMIZE_FOR lines in protos and generates code
#       with the specified optimization mode (lite or speed). For fuzzer builds
#       this defaults to speed to support libprotobuf-mutator.
#   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_grpc",
                             "gen_grpc_gmock",
                             "gen_cpp_mode",

                             # 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_grpc)) {
      gen_grpc = false
    }
    if (gen_grpc && !defined(gen_grpc_gmock)) {
      gen_grpc_gmock = false
    }
    if (defined(gen_cpp_mode)) {
      gen_cpp_mode = "${gen_cpp_mode}:"
    } else {
      gen_cpp_mode = ""
    }

    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=${gen_cpp_mode}${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_grpc && !gen_python) {
      args += [ "--cpp_out=${gen_cpp_mode}${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",

          # TODO(oka): we should not have to use all_dependent_pkg_deps here, because there is no
          # inherent reason that all users of this target should depend on some external
          # dependency. Remove this after no user uses it.
          "all_dependent_pkg_deps",
        ])
    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
    }

    # Protobuf 3.7.0 introduced generated code that is sometimes unreachable.
    cflags_cc = [ "-Wno-unreachable-code" ]
  }
}

# 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.
#   gen_grpc (optional)
#       If true, generates Go GRPC.
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"
    if (defined(invoker.gen_grpc) && invoker.gen_grpc) {
      go_out_prefix = "plugins=grpc:"
    } else {
      go_out_prefix = ""
    }
    args = [
      "protoc",
      "--proto_path",
      proto_in_dir,
      "--proto_path",
      "${sysroot}/usr/share/proto",
      "--go_out",
      "${go_out_prefix}${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" ]
    }
  }
}
