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

assert(is_win)

import("//build/config/python.gni")
import("//build/config/win/visual_studio_version.gni")

# This template defines a rule to invoke the MS IDL compiler. The generated
# source code will be compiled and linked into targets that depend on this.
#
# Parameters
#
#   sources
#       List of .idl file to process.
#
#   header_file (optional)
#       File name of generated header file.  Defaults to the basename of the
#       source idl file with a .h extension.
#
#   out_dir (optional)
#       Directory to write the generated files to. Defaults to target_gen_dir.
#
#   generated_dir (optional)
#       Directory where generated files were previously persisted.
#       Defaults to third_party\win_build_output\midl\|out_dir|.
#
#   dynamic_guids (optional)
#       If the GUIDs are not constant across builds, the current GUID
#       substitutions.
#       |dynamic_guids| is of the form:
#         "PLACEHOLDER-GUID-158428a4-6014-4978-83ba-9fad0dabe791="
#         "3d852661-c795-4d20-9b95-5561e9a1d2d9,"
#         "PLACEHOLDER-GUID-63B8FFB1-5314-48C9-9C57-93EC8BC6184B="
#         "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83".
#       See midl.py for more details.
#
#   writes_tlb (optional)
#       Whether a .tlb file should be added to outputs. Defaults to false.
#
#   writes_proxy(optional)
#       Whether a _p.c file should be added to outputs. Defaults to true.
#
#   writes_dlldata(optional)
#       Whether a .dlldata.c file should be added to outputs. Defaults to true.
#
#   deps (optional)
#
#   defines (optional)
#       Build time defines to be passed to midl.exe as /D parameter.
#
#   visibility (optional)

template("midl") {
  action_name = "${target_name}_idl_action"
  source_set_name = target_name

  assert(defined(invoker.sources), "Source must be defined for $target_name")

  if (defined(invoker.out_dir)) {
    out_dir = invoker.out_dir
  } else {
    out_dir = target_gen_dir
  }

  if (defined(invoker.generated_dir)) {
    generated_dir = rebase_path(invoker.generated_dir)
  } else {
    # midl.py expects 'gen' to be replaced with 'midl'.
    generated_dir = rebase_path("//third_party/win_build_output") + "/midl/" +
                    rebase_path(out_dir, root_gen_dir)
  }

  if (defined(invoker.dynamic_guids)) {
    dynamic_guids = invoker.dynamic_guids
  } else {
    dynamic_guids = "none"
  }

  if (defined(invoker.header_file)) {
    header_file = invoker.header_file
  } else {
    header_file = "{{source_name_part}}.h"
  }

  if (defined(invoker.writes_tlb)) {
    writes_tlb = invoker.writes_tlb
  } else {
    writes_tlb = false
  }

  if (defined(invoker.writes_proxy)) {
    writes_proxy = invoker.writes_proxy
  } else {
    writes_proxy = true
  }

  if (defined(invoker.writes_dlldata)) {
    writes_dlldata = invoker.writes_dlldata
  } else {
    writes_dlldata = true
  }

  if (writes_tlb) {
    type_library_file = "{{source_name_part}}.tlb"
  } else {
    type_library_file = "none"
  }

  if (writes_dlldata) {
    dlldata_file = "{{source_name_part}}.dlldata.c"
  } else {
    dlldata_file = "none"
  }

  if (writes_proxy) {
    proxy_file = "{{source_name_part}}_p.c"
  } else {
    proxy_file = "none"
  }

  interface_identifier_file = "{{source_name_part}}_i.c"

  # TODO(crbug.com/1112471): Get this to run cleanly under Python 3.
  python2_action_foreach(action_name) {
    visibility = [ ":$source_set_name" ]
    script = "//build/toolchain/win/midl.py"

    sources = invoker.sources

    outputs = [
      "$out_dir/$header_file",
      "$out_dir/$interface_identifier_file",
    ]

    # These files are only added to outputs if the invoker so desires, as it
    # they are not always generated depending on the content of the input idl
    # file.
    if (writes_tlb) {
      outputs += [ "$out_dir/$type_library_file" ]
    }
    if (writes_dlldata) {
      outputs += [ "$out_dir/$dlldata_file" ]
    }
    if (writes_proxy) {
      outputs += [ "$out_dir/$proxy_file" ]
    }

    if (current_cpu == "x86") {
      win_tool_arch = "environment.x86"
      idl_target_platform = "win32"
    } else if (current_cpu == "x64") {
      win_tool_arch = "environment.x64"
      idl_target_platform = "x64"
    } else if (current_cpu == "arm64") {
      win_tool_arch = "environment.arm64"
      idl_target_platform = "arm64"
    } else {
      assert(false, "Need environment for this arch")
    }

    args = [
      win_tool_arch,
      generated_dir,
      rebase_path(out_dir, root_build_dir),
      dynamic_guids,
      type_library_file,
      header_file,
      dlldata_file,
      interface_identifier_file,
      proxy_file,
      rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang-cl.exe",
                  root_build_dir),
      "{{source}}",
      "/char",
      "signed",
      "/env",
      idl_target_platform,
      "/Oicf",
    ]

    if (defined(invoker.defines)) {
      foreach(define, invoker.defines) {
        args += [ "/D" + define ]
      }
    }

    forward_variables_from(invoker, [ "deps" ])
  }

  source_set(target_name) {
    forward_variables_from(invoker, [ "visibility" ])

    # We only compile the IID files from the IDL tool rather than all outputs.
    sources = process_file_template(invoker.sources,
                                    [ "$out_dir/$interface_identifier_file" ])

    public_deps = [ ":$action_name" ]
  }
}
