#!/usr/bin/env python3
# Copyright (c) 2012 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.
"""
A simple wrapper for protoc.
Script for //third_party/protobuf/proto_library.gni .
Features:
- Inserts #include for extra header automatically.
- Prevents bad proto names.
- Works around protoc's bad descriptor file generation.
  Ninja expects the format:
  target: deps
  But protoc just outputs:
  deps
  This script adds the "target:" part.
"""

from __future__ import print_function
import argparse
import os.path
import subprocess
import sys

PROTOC_INCLUDE_POINT = "// @@protoc_insertion_point(includes)"


def FormatGeneratorOptions(options):
  if not options:
    return ""
  if options.endswith(":"):
    return options
  return options + ":"


def VerifyProtoNames(protos):
  for filename in protos:
    if "-" in filename:
      raise RuntimeError("Proto file names must not contain hyphens "
                         "(see http://crbug.com/386125 for more information).")


def StripProtoExtension(filename):
  if not filename.endswith(".proto"):
    raise RuntimeError(f"Invalid proto filename extension: {filename} .")
  return filename.rsplit(".", 1)[0]


def WriteIncludes(headers, include):
  for filename in headers:
    include_point_found = False
    contents = []
    with open(filename, encoding="utf-8") as f:
      for line in f:
        stripped_line = line.strip()
        contents.append(stripped_line)
        if stripped_line == PROTOC_INCLUDE_POINT:
          if include_point_found:
            raise RuntimeError("Multiple include points found.")
          include_point_found = True
          extra_statement = f'#include "{include}"'
          contents.append(extra_statement)

      if not include_point_found:
        raise RuntimeError(f"Include point not found in header: {filename} .")

    with open(filename, "w", encoding="utf-8") as f:
      for line in contents:
        print(line, file=f)


def main(argv):
  parser = argparse.ArgumentParser()
  parser.add_argument(
      "--protoc", required=True, help="Relative path to compiler.")

  parser.add_argument(
      "--proto-in-dir",
      required=True,
      help="Base directory with source protos.")
  parser.add_argument(
      "--cc-out-dir", help="Output directory for standard C++ generator.")
  parser.add_argument(
      "--py-out-dir", help="Output directory for standard Python generator.")
  parser.add_argument(
      "--js-out-dir", help="Output directory for standard JS generator.")
  parser.add_argument(
      "--plugin-out-dir", help="Output directory for custom generator plugin.")

  parser.add_argument(
      "--enable-kythe-annotations",
      action="store_true",
      help="Enable generation of Kythe kzip, used for "
      "codesearch.")
  parser.add_argument(
      "--plugin", help="Relative path to custom generator plugin.")
  parser.add_argument(
      "--plugin-options", help="Custom generator plugin options.")
  parser.add_argument("--cc-options", help="Standard C++ generator options.")
  parser.add_argument(
      "--include", help="Name of include to insert into generated headers.")
  parser.add_argument(
      "--import-dir",
      action="append",
      default=[],
      help="Extra import directory for protos, can be repeated.")
  parser.add_argument(
      "--descriptor-set-out", help="Path to write a descriptor.")
  parser.add_argument(
      "--descriptor-set-dependency-file",
      help="Path to write the dependency file for descriptor set.")
  # The meaning of this flag is flipped compared to the corresponding protoc
  # flag due to this script previously passing --include_imports. Removing the
  # --include_imports is likely to have unintended consequences.
  parser.add_argument(
      "--exclude-imports",
      help="Do not include imported files into generated descriptor.",
      action="store_true",
      default=False)
  parser.add_argument(
      "protos", nargs="+", help="Input protobuf definition file(s).")

  options = parser.parse_args(argv)

  proto_dir = os.path.relpath(options.proto_in_dir)
  protoc_cmd = [os.path.realpath(options.protoc)]

  protos = options.protos
  headers = []
  VerifyProtoNames(protos)

  if options.py_out_dir:
    protoc_cmd += ["--python_out", options.py_out_dir]

  if options.js_out_dir:
    protoc_cmd += [
        "--js_out",
        "one_output_file_per_input_file,binary:" + options.js_out_dir
    ]

  if options.cc_out_dir:
    cc_out_dir = options.cc_out_dir
    cc_options_list = []
    if options.enable_kythe_annotations:
      cc_options_list.extend([
          "annotate_headers", "annotation_pragma_name=kythe_metadata",
          "annotation_guard_name=KYTHE_IS_RUNNING"
      ])

    # cc_options will likely have trailing colon so needs to be inserted at the
    # end.
    if options.cc_options:
      cc_options_list.append(options.cc_options)

    cc_options = FormatGeneratorOptions(",".join(cc_options_list))
    protoc_cmd += ["--cpp_out", cc_options + cc_out_dir]
    for filename in protos:
      stripped_name = StripProtoExtension(filename)
      headers.append(os.path.join(cc_out_dir, stripped_name + ".pb.h"))

  if options.plugin_out_dir:
    plugin_options = FormatGeneratorOptions(options.plugin_options)
    protoc_cmd += [
        "--plugin", "protoc-gen-plugin=" + os.path.relpath(options.plugin),
        "--plugin_out", plugin_options + options.plugin_out_dir
    ]

  protoc_cmd += ["--proto_path", proto_dir]
  for path in options.import_dir:
    protoc_cmd += ["--proto_path", path]

  protoc_cmd += [os.path.join(proto_dir, name) for name in protos]

  if options.descriptor_set_out:
    protoc_cmd += ["--descriptor_set_out", options.descriptor_set_out]
    if not options.exclude_imports:
      protoc_cmd += ["--include_imports"]

  dependency_file_data = None
  if options.descriptor_set_out and options.descriptor_set_dependency_file:
    protoc_cmd += ["--dependency_out", options.descriptor_set_dependency_file]
    ret = subprocess.call(protoc_cmd)

    with open(options.descriptor_set_dependency_file, "rb") as f:
      dependency_file_data = f.read().decode("utf-8")

  ret = subprocess.call(protoc_cmd)
  if ret != 0:
    if ret <= -100:
      # Windows error codes such as 0xC0000005 and 0xC0000409 are much easier to
      # recognize and differentiate in hex. In order to print them as unsigned
      # hex we need to add 4 Gig to them.
      error_number = f"0x{ret + (1 << 32):08X}"
    else:
      error_number = f"{ret}"
    raise RuntimeError(f"Protoc has returned non-zero status: {error_number}")

  if dependency_file_data:
    with open(options.descriptor_set_dependency_file, "w", encoding="utf-8") as f:  #pylint: disable=line-too-long
      f.write(options.descriptor_set_out + ":")
      f.write(dependency_file_data)

  if options.include:
    WriteIncludes(headers, options.include)


if __name__ == "__main__":
  try:
    main(sys.argv[1:])
  except RuntimeError as e:
    print(e, file=sys.stderr)
    sys.exit(1)
