#!/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
import tempfile

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("Invalid proto filename extension: "
                       "{0} .".format(filename))
  return filename.rsplit(".", 1)[0]


def WriteIncludes(headers, include):
  for filename in headers:
    include_point_found = False
    contents = []
    with open(filename) 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 = "#include \"{0}\"".format(include)
          contents.append(extra_statement)

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

    with open(filename, "w") 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.")
  #   TODO(crbug.com/1237958): Remove allow_optional when proto rolls to 3.15.
  parser.add_argument("--allow-optional",
                      action='store_true',
                      help="Enables experimental_allow_proto3_optional.")
  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)

    if options.allow_optional:
      protoc_cmd += ["--experimental_allow_proto3_optional"]

    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 = "0x%08X" % (ret + (1 << 32))
    else:
      error_number = "%d" % ret
    raise RuntimeError("Protoc has returned non-zero status: "
                       "{0}".format(error_number))

  if dependency_file_data:
    with open(options.descriptor_set_dependency_file, 'w') as f:
      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)
