#!/usr/bin/env python3
#
# Copyright 2013 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.

import logging
import multiprocessing
import optparse
import os
import re
import shutil
import sys
import time
import zipfile

from util import build_utils
from util import md5_check
from util import jar_info_utils
from util import server_utils

sys.path.insert(
    0,
    os.path.join(build_utils.DIR_SOURCE_ROOT, 'third_party', 'colorama', 'src'))
import colorama

_JAVAC_EXTRACTOR = os.path.join(build_utils.DIR_SOURCE_ROOT, 'third_party',
                                'android_prebuilts', 'build_tools', 'common',
                                'framework', 'javac_extractor.jar')

# Add a check here to cause the suggested fix to be applied while compiling.
# Use this when trying to enable more checks.
ERRORPRONE_CHECKS_TO_APPLY = []

# Full list of checks: https://errorprone.info/bugpatterns
ERRORPRONE_WARNINGS_TO_DISABLE = [
    # The following are super useful, but existing issues need to be fixed first
    # before they can start failing the build on new errors.
    'InvalidParam',
    'InvalidLink',
    'InvalidInlineTag',
    'EmptyBlockTag',
    'PublicConstructorForAbstractClass',
    'InvalidBlockTag',
    'StaticAssignmentInConstructor',
    'MutablePublicArray',
    'UnescapedEntity',
    'NonCanonicalType',
    'AlmostJavadoc',
    # TODO(crbug.com/834807): Follow steps in bug
    'DoubleBraceInitialization',
    # TODO(crbug.com/834790): Follow steps in bug.
    'CatchAndPrintStackTrace',
    # TODO(crbug.com/801210): Follow steps in bug.
    'SynchronizeOnNonFinalField',
    # TODO(crbug.com/802073): Follow steps in bug.
    'TypeParameterUnusedInFormals',
    # TODO(crbug.com/803484): Follow steps in bug.
    'CatchFail',
    # TODO(crbug.com/803485): Follow steps in bug.
    'JUnitAmbiguousTestClass',
    # Android platform default is always UTF-8.
    # https://developer.android.com/reference/java/nio/charset/Charset.html#defaultCharset()
    'DefaultCharset',
    # Low priority since the alternatives still work.
    'JdkObsolete',
    # We don't use that many lambdas.
    'FunctionalInterfaceClash',
    # There are lots of times when we just want to post a task.
    'FutureReturnValueIgnored',
    # Nice to be explicit about operators, but not necessary.
    'OperatorPrecedence',
    # Just false positives in our code.
    'ThreadJoinLoop',
    # Low priority corner cases with String.split.
    # Linking Guava and using Splitter was rejected
    # in the https://chromium-review.googlesource.com/c/chromium/src/+/871630.
    'StringSplitter',
    # Preferred to use another method since it propagates exceptions better.
    'ClassNewInstance',
    # Nice to have static inner classes but not necessary.
    'ClassCanBeStatic',
    # Explicit is better than implicit.
    'FloatCast',
    # Results in false positives.
    'ThreadLocalUsage',
    # Also just false positives.
    'Finally',
    # False positives for Chromium.
    'FragmentNotInstantiable',
    # Low priority to fix.
    'HidingField',
    # Low priority.
    'IntLongMath',
    # Low priority.
    'BadComparable',
    # Low priority.
    'EqualsHashCode',
    # Nice to fix but low priority.
    'TypeParameterShadowing',
    # Good to have immutable enums, also low priority.
    'ImmutableEnumChecker',
    # False positives for testing.
    'InputStreamSlowMultibyteRead',
    # Nice to have better primitives.
    'BoxedPrimitiveConstructor',
    # Not necessary for tests.
    'OverrideThrowableToString',
    # Nice to have better type safety.
    'CollectionToArraySafeParameter',
    # Makes logcat debugging more difficult, and does not provide obvious
    # benefits in the Chromium codebase.
    'ObjectToString',
    # Triggers on private methods that are @CalledByNative.
    'UnusedMethod',
    # Triggers on generated R.java files.
    'UnusedVariable',
    # Not that useful.
    'UnsafeReflectiveConstructionCast',
    # Not that useful.
    'MixedMutabilityReturnType',
    # Nice to have.
    'EqualsGetClass',
    # A lot of false-positives from CharSequence.equals().
    'UndefinedEquals',
    # Nice to have.
    'ExtendingJUnitAssert',
    # Nice to have.
    'SystemExitOutsideMain',
    # Nice to have.
    'TypeParameterNaming',
    # Nice to have.
    'UnusedException',
    # Nice to have.
    'UngroupedOverloads',
    # Nice to have.
    'FunctionalInterfaceClash',
    # Nice to have.
    'InconsistentOverloads',
    # Dagger generated code triggers this.
    'SameNameButDifferent',
    # Nice to have.
    'UnnecessaryLambda',
    # Nice to have.
    'UnnecessaryAnonymousClass',
    # Nice to have.
    'LiteProtoToString',
    # Nice to have.
    'MissingSummary',
    # Nice to have.
    'ReturnFromVoid',
    # Nice to have.
    'EmptyCatch',
    # Nice to have.
    'BadImport',
    # Nice to have.
    'UseCorrectAssertInTests',
    # Nice to have.
    'InlineFormatString',
    # Nice to have.
    'DefaultPackage',
    # Must be off since we are now passing in annotation processor generated
    # code as a source jar (deduplicating work with turbine).
    'RefersToDaggerCodegen',
    # We already have presubmit checks for this. Not necessary to warn on
    # every build.
    'RemoveUnusedImports',
    # We do not care about unnecessary parenthesis enough to check for them.
    'UnnecessaryParentheses',
]

# Full list of checks: https://errorprone.info/bugpatterns
# Only those marked as "experimental" need to be listed here in order to be
# enabled.
ERRORPRONE_WARNINGS_TO_ENABLE = [
    'BinderIdentityRestoredDangerously',
    'EmptyIf',
    'EqualsBrokenForNull',
    'InvalidThrows',
    'LongLiteralLowerCaseSuffix',
    'MultiVariableDeclaration',
    'ParameterNotNullable',
    'RedundantOverride',
    'StaticQualifiedUsingExpression',
    'StringEquality',
    'TimeUnitMismatch',
    'UnnecessaryStaticImport',
    'UseBinds',
    'WildcardImport',
]


def ProcessJavacOutput(output):
  fileline_prefix = r'(?P<fileline>(?P<file>[-.\w/\\]+.java):(?P<line>[0-9]+):)'
  warning_re = re.compile(fileline_prefix +
                          r'(?P<full_message> warning: (?P<message>.*))$')
  error_re = re.compile(fileline_prefix +
                        r'(?P<full_message> (?P<message>.*))$')
  marker_re = re.compile(r'\s*(?P<marker>\^)\s*$')

  # These warnings cannot be suppressed even for third party code. Deprecation
  # warnings especially do not help since we must support older android version.
  deprecated_re = re.compile(
      r'(Note: .* uses? or overrides? a deprecated API.)$')
  unchecked_re = re.compile(
      r'(Note: .* uses? unchecked or unsafe operations.)$')
  recompile_re = re.compile(r'(Note: Recompile with -Xlint:.* for details.)$')

  activity_re = re.compile(r'^(?P<prefix>\s*location: )class Activity$')

  warning_color = ['full_message', colorama.Fore.YELLOW + colorama.Style.DIM]
  error_color = ['full_message', colorama.Fore.MAGENTA + colorama.Style.BRIGHT]
  marker_color = ['marker', colorama.Fore.BLUE + colorama.Style.BRIGHT]

  def Colorize(line, regex, color):
    match = regex.match(line)
    start = match.start(color[0])
    end = match.end(color[0])
    return (line[:start] + color[1] + line[start:end] + colorama.Fore.RESET +
            colorama.Style.RESET_ALL + line[end:])

  def ApplyFilters(line):
    return not (deprecated_re.match(line) or unchecked_re.match(line)
                or recompile_re.match(line))

  def Elaborate(line):
    if activity_re.match(line):
      prefix = ' ' * activity_re.match(line).end('prefix')
      return '{}\n{}Expecting a FragmentActivity? See {}'.format(
          line, prefix, 'docs/ui/android/bytecode_rewriting.md')
    return line

  def ApplyColors(line):
    if warning_re.match(line):
      line = Colorize(line, warning_re, warning_color)
    elif error_re.match(line):
      line = Colorize(line, error_re, error_color)
    elif marker_re.match(line):
      line = Colorize(line, marker_re, marker_color)
    return line

  lines = (l for l in output.split('\n') if ApplyFilters(l))
  lines = (ApplyColors(Elaborate(l)) for l in lines)
  return '\n'.join(lines)


def _ParsePackageAndClassNames(java_file):
  package_name = ''
  class_names = []
  with open(java_file) as f:
    for l in f:
      # Strip unindented comments.
      # Considers a leading * as a continuation of a multi-line comment (our
      # linter doesn't enforce a space before it like there should be).
      l = re.sub(r'^(?://.*|/?\*.*?(?:\*/\s*|$))', '', l)

      m = re.match(r'package\s+(.*?);', l)
      if m and not package_name:
        package_name = m.group(1)

      # Not exactly a proper parser, but works for sources that Chrome uses.
      # In order to not match nested classes, it just checks for lack of indent.
      m = re.match(r'(?:\S.*?)?(?:class|@?interface|enum)\s+(.+?)\b', l)
      if m:
        class_names.append(m.group(1))
  return package_name, class_names


def _ProcessJavaFileForInfo(java_file):
  package_name, class_names = _ParsePackageAndClassNames(java_file)
  return java_file, package_name, class_names


class _InfoFileContext(object):
  """Manages the creation of the class->source file .info file."""

  def __init__(self, chromium_code, excluded_globs):
    self._chromium_code = chromium_code
    self._excluded_globs = excluded_globs
    # Map of .java path -> .srcjar/nested/path.java.
    self._srcjar_files = {}
    # List of generators from pool.imap_unordered().
    self._results = []
    # Lazily created multiprocessing.Pool.
    self._pool = None

  def AddSrcJarSources(self, srcjar_path, extracted_paths, parent_dir):
    for path in extracted_paths:
      # We want the path inside the srcjar so the viewer can have a tree
      # structure.
      self._srcjar_files[path] = '{}/{}'.format(
          srcjar_path, os.path.relpath(path, parent_dir))

  def SubmitFiles(self, java_files):
    if self._pool is None:
      # Restrict to just one process to not slow down compiling. Compiling
      # is always slower.
      self._pool = multiprocessing.Pool(1)
    logging.info('Submitting %d files for info', len(java_files))
    self._results.append(
        self._pool.imap_unordered(
            _ProcessJavaFileForInfo, java_files, chunksize=1000))

  def _CheckPathMatchesClassName(self, java_file, package_name, class_name):
    parts = package_name.split('.') + [class_name + '.java']
    expected_path_suffix = os.path.sep.join(parts)
    if not java_file.endswith(expected_path_suffix):
      raise Exception(('Java package+class name do not match its path.\n'
                       'Actual path: %s\nExpected path: %s') %
                      (java_file, expected_path_suffix))

  def _ProcessInfo(self, java_file, package_name, class_names, source):
    for class_name in class_names:
      yield '{}.{}'.format(package_name, class_name)
      # Skip aidl srcjars since they don't indent code correctly.
      if '_aidl.srcjar' in source:
        continue
      assert not self._chromium_code or len(class_names) == 1, (
          'Chromium java files must only have one class: {}'.format(source))
      if self._chromium_code:
        # This check is not necessary but nice to check this somewhere.
        self._CheckPathMatchesClassName(java_file, package_name, class_names[0])

  def _ShouldIncludeInJarInfo(self, fully_qualified_name):
    name_as_class_glob = fully_qualified_name.replace('.', '/') + '.class'
    return not build_utils.MatchesGlob(name_as_class_glob, self._excluded_globs)

  def _Collect(self):
    if self._pool is None:
      return {}
    ret = {}
    for result in self._results:
      for java_file, package_name, class_names in result:
        source = self._srcjar_files.get(java_file, java_file)
        for fully_qualified_name in self._ProcessInfo(java_file, package_name,
                                                      class_names, source):
          if self._ShouldIncludeInJarInfo(fully_qualified_name):
            ret[fully_qualified_name] = java_file
    self._pool.terminate()
    return ret

  def __del__(self):
    # Work around for Python 2.x bug with multiprocessing and daemon threads:
    # https://bugs.python.org/issue4106
    if self._pool is not None:
      logging.info('Joining multiprocessing.Pool')
      self._pool.terminate()
      self._pool.join()
      logging.info('Done.')

  def Commit(self, output_path):
    """Writes a .jar.info file.

    Maps fully qualified names for classes to either the java file that they
    are defined in or the path of the srcjar that they came from.
    """
    logging.info('Collecting info file entries')
    entries = self._Collect()

    logging.info('Writing info file: %s', output_path)
    with build_utils.AtomicOutput(output_path, mode='wb') as f:
      jar_info_utils.WriteJarInfoFile(f, entries, self._srcjar_files)
    logging.info('Completed info file: %s', output_path)


def _CreateJarFile(jar_path, service_provider_configuration_dir,
                   additional_jar_files, classes_dir):
  logging.info('Start creating jar file: %s', jar_path)
  with build_utils.AtomicOutput(jar_path) as f:
    with zipfile.ZipFile(f.name, 'w') as z:
      build_utils.ZipDir(z, classes_dir)
      if service_provider_configuration_dir:
        config_files = build_utils.FindInDirectory(
            service_provider_configuration_dir)
        for config_file in config_files:
          zip_path = os.path.relpath(config_file,
                                     service_provider_configuration_dir)
          build_utils.AddToZipHermetic(z, zip_path, src_path=config_file)

      if additional_jar_files:
        for src_path, zip_path in additional_jar_files:
          build_utils.AddToZipHermetic(z, zip_path, src_path=src_path)
  logging.info('Completed jar file: %s', jar_path)


def _OnStaleMd5(options, javac_cmd, javac_args, java_files):
  logging.info('Starting _OnStaleMd5')
  if options.enable_kythe_annotations:
    # Kythe requires those env variables to be set and compile_java.py does the
    # same
    if not os.environ.get('KYTHE_ROOT_DIRECTORY') or \
        not os.environ.get('KYTHE_OUTPUT_DIRECTORY'):
      raise Exception('--enable-kythe-annotations requires '
                      'KYTHE_ROOT_DIRECTORY and KYTHE_OUTPUT_DIRECTORY '
                      'environment variables to be set.')
    javac_extractor_cmd = build_utils.JavaCmd() + [
        '-jar',
        _JAVAC_EXTRACTOR,
    ]
    try:
      _RunCompiler(options, javac_extractor_cmd + javac_args, java_files,
                   options.classpath, options.jar_path + '.javac_extractor',
                   save_outputs=False),
    except build_utils.CalledProcessError as e:
      # Having no index for particular target is better than failing entire
      # codesearch. Log and error and move on.
      logging.error('Could not generate kzip: %s', e)

  # Compiles with Error Prone take twice as long to run as pure javac. Thus GN
  # rules run both in parallel, with Error Prone only used for checks.
  _RunCompiler(options,
               javac_cmd + javac_args,
               java_files,
               options.classpath,
               options.jar_path,
               save_outputs=not options.enable_errorprone)
  logging.info('Completed all steps in _OnStaleMd5')


def _RunCompiler(options, javac_cmd, java_files, classpath, jar_path,
                 save_outputs=True):
  logging.info('Starting _RunCompiler')

  # Compiles with Error Prone take twice as long to run as pure javac. Thus GN
  # rules run both in parallel, with Error Prone only used for checks.
  save_outputs = not options.enable_errorprone

  # Use jar_path's directory to ensure paths are relative (needed for goma).
  temp_dir = jar_path + '.staging'
  shutil.rmtree(temp_dir, True)
  os.makedirs(temp_dir)
  try:
    classes_dir = os.path.join(temp_dir, 'classes')
    service_provider_configuration = os.path.join(
        temp_dir, 'service_provider_configuration')

    if save_outputs:
      input_srcjars_dir = os.path.join(options.generated_dir, 'input_srcjars')
      annotation_processor_outputs_dir = os.path.join(
          options.generated_dir, 'annotation_processor_outputs')
      # Delete any stale files in the generated directory. The purpose of
      # options.generated_dir is for codesearch.
      shutil.rmtree(options.generated_dir, True)
      info_file_context = _InfoFileContext(options.chromium_code,
                                           options.jar_info_exclude_globs)
    else:
      input_srcjars_dir = os.path.join(temp_dir, 'input_srcjars')
      annotation_processor_outputs_dir = os.path.join(
          temp_dir, 'annotation_processor_outputs')

    if options.java_srcjars:
      logging.info('Extracting srcjars to %s', input_srcjars_dir)
      build_utils.MakeDirectory(input_srcjars_dir)
      for srcjar in options.java_srcjars:
        extracted_files = build_utils.ExtractAll(
            srcjar, no_clobber=True, path=input_srcjars_dir, pattern='*.java')
        java_files.extend(extracted_files)
        if save_outputs:
          info_file_context.AddSrcJarSources(srcjar, extracted_files,
                                             input_srcjars_dir)
      logging.info('Done extracting srcjars')

    if options.header_jar:
      logging.info('Extracting service provider configs')
      # Extract META-INF/services/* so that it can be copied into the output
      # .jar
      build_utils.ExtractAll(options.header_jar,
                             no_clobber=True,
                             path=service_provider_configuration,
                             pattern='META-INF/services/*')
      logging.info('Done extracting service provider configs')

    if save_outputs and java_files:
      info_file_context.SubmitFiles(java_files)

    if java_files:
      # Don't include the output directory in the initial set of args since it
      # being in a temp dir makes it unstable (breaks md5 stamping).
      cmd = list(javac_cmd)
      os.makedirs(classes_dir)
      cmd += ['-d', classes_dir]

      if options.processors:
        os.makedirs(annotation_processor_outputs_dir)
        cmd += ['-s', annotation_processor_outputs_dir]

      if classpath:
        cmd += ['-classpath', ':'.join(classpath)]

      # Pass source paths as response files to avoid extremely long command
      # lines that are tedius to debug.
      java_files_rsp_path = os.path.join(temp_dir, 'files_list.txt')
      with open(java_files_rsp_path, 'w') as f:
        f.write(' '.join(java_files))
      cmd += ['@' + java_files_rsp_path]

      logging.debug('Build command %s', cmd)
      start = time.time()
      build_utils.CheckOutput(cmd,
                              print_stdout=options.chromium_code,
                              stdout_filter=ProcessJavacOutput,
                              stderr_filter=ProcessJavacOutput,
                              fail_on_output=options.warnings_as_errors)
      end = time.time() - start
      logging.info('Java compilation took %ss', end)

    if save_outputs:
      if options.processors:
        annotation_processor_java_files = build_utils.FindInDirectory(
            annotation_processor_outputs_dir)
        if annotation_processor_java_files:
          info_file_context.SubmitFiles(annotation_processor_java_files)

      _CreateJarFile(jar_path, service_provider_configuration,
                     options.additional_jar_files, classes_dir)

      info_file_context.Commit(jar_path + '.info')
    else:
      build_utils.Touch(jar_path)

    logging.info('Completed all steps in _RunCompiler')
  finally:
    shutil.rmtree(temp_dir)


def _ParseOptions(argv):
  parser = optparse.OptionParser()
  build_utils.AddDepfileOption(parser)

  parser.add_option('--target-name', help='Fully qualified GN target name.')
  parser.add_option('--skip-build-server',
                    action='store_true',
                    help='Avoid using the build server.')
  parser.add_option(
      '--java-srcjars',
      action='append',
      default=[],
      help='List of srcjars to include in compilation.')
  parser.add_option(
      '--generated-dir',
      help='Subdirectory within target_gen_dir to place extracted srcjars and '
      'annotation processor output for codesearch to find.')
  parser.add_option(
      '--bootclasspath',
      action='append',
      default=[],
      help='Boot classpath for javac. If this is specified multiple times, '
      'they will all be appended to construct the classpath.')
  parser.add_option(
      '--java-version',
      help='Java language version to use in -source and -target args to javac.')
  parser.add_option('--classpath', action='append', help='Classpath to use.')
  parser.add_option(
      '--processors',
      action='append',
      help='GN list of annotation processor main classes.')
  parser.add_option(
      '--processorpath',
      action='append',
      help='GN list of jars that comprise the classpath used for Annotation '
      'Processors.')
  parser.add_option(
      '--processor-arg',
      dest='processor_args',
      action='append',
      help='key=value arguments for the annotation processors.')
  parser.add_option(
      '--additional-jar-file',
      dest='additional_jar_files',
      action='append',
      help='Additional files to package into jar. By default, only Java .class '
      'files are packaged into the jar. Files should be specified in '
      'format <filename>:<path to be placed in jar>.')
  parser.add_option(
      '--jar-info-exclude-globs',
      help='GN list of exclude globs to filter from generated .info files.')
  parser.add_option(
      '--chromium-code',
      type='int',
      help='Whether code being compiled should be built with stricter '
      'warnings for chromium code.')
  parser.add_option(
      '--gomacc-path', help='When set, prefix javac command with gomacc')
  parser.add_option(
      '--errorprone-path', help='Use the Errorprone compiler at this path.')
  parser.add_option(
      '--enable-errorprone',
      action='store_true',
      help='Enable errorprone checks')
  parser.add_option(
      '--warnings-as-errors',
      action='store_true',
      help='Treat all warnings as errors.')
  parser.add_option('--jar-path', help='Jar output path.')
  parser.add_option(
      '--javac-arg',
      action='append',
      default=[],
      help='Additional arguments to pass to javac.')
  parser.add_option(
      '--enable-kythe-annotations',
      action='store_true',
      help='Enable generation of Kythe kzip, used for codesearch. Ensure '
      'proper environment variables are set before using this flag.')
  parser.add_option(
      '--header-jar',
      help='This is the header jar for the current target that contains '
      'META-INF/services/* files to be included in the output jar.')

  options, args = parser.parse_args(argv)
  build_utils.CheckOptions(options, parser, required=('jar_path', ))

  options.bootclasspath = build_utils.ParseGnList(options.bootclasspath)
  options.classpath = build_utils.ParseGnList(options.classpath)
  options.processorpath = build_utils.ParseGnList(options.processorpath)
  options.processors = build_utils.ParseGnList(options.processors)
  options.java_srcjars = build_utils.ParseGnList(options.java_srcjars)
  options.jar_info_exclude_globs = build_utils.ParseGnList(
      options.jar_info_exclude_globs)

  additional_jar_files = []
  for arg in options.additional_jar_files or []:
    filepath, jar_filepath = arg.split(':')
    additional_jar_files.append((filepath, jar_filepath))
  options.additional_jar_files = additional_jar_files

  java_files = []
  for arg in args:
    # Interpret a path prefixed with @ as a file containing a list of sources.
    if arg.startswith('@'):
      java_files.extend(build_utils.ReadSourcesList(arg[1:]))
    else:
      java_files.append(arg)

  return options, java_files


def main(argv):
  build_utils.InitLogging('JAVAC_DEBUG')
  argv = build_utils.ExpandFileArgs(argv)
  options, java_files = _ParseOptions(argv)

  # Only use the build server for errorprone runs.
  if (options.enable_errorprone and not options.skip_build_server
      and server_utils.MaybeRunCommand(name=options.target_name,
                                       argv=sys.argv,
                                       stamp_file=options.jar_path)):
    return

  colorama.init()
  javac_cmd = []
  if options.gomacc_path:
    javac_cmd.append(options.gomacc_path)
  javac_cmd.append(build_utils.JAVAC_PATH)

  javac_args = [
      '-g',
      # Chromium only allows UTF8 source files.  Being explicit avoids
      # javac pulling a default encoding from the user's environment.
      '-encoding',
      'UTF-8',
      # Prevent compiler from compiling .java files not listed as inputs.
      # See: http://blog.ltgt.net/most-build-tools-misuse-javac/
      '-sourcepath',
      ':',
  ]

  if options.enable_errorprone:
    # All errorprone args are passed space-separated in a single arg.
    errorprone_flags = ['-Xplugin:ErrorProne']
    # Make everything a warning so that when treat_warnings_as_errors is false,
    # they do not fail the build.
    errorprone_flags += ['-XepAllErrorsAsWarnings']
    # Don't check generated files.
    errorprone_flags += ['-XepDisableWarningsInGeneratedCode']
    errorprone_flags.extend('-Xep:{}:OFF'.format(x)
                            for x in ERRORPRONE_WARNINGS_TO_DISABLE)
    errorprone_flags.extend('-Xep:{}:WARN'.format(x)
                            for x in ERRORPRONE_WARNINGS_TO_ENABLE)

    if ERRORPRONE_CHECKS_TO_APPLY:
      errorprone_flags += [
          '-XepPatchLocation:IN_PLACE',
          '-XepPatchChecks:,' + ','.join(ERRORPRONE_CHECKS_TO_APPLY)
      ]

    javac_args += ['-XDcompilePolicy=simple', ' '.join(errorprone_flags)]

    # This flag quits errorprone after checks and before code generation, since
    # we do not need errorprone outputs, this speeds up errorprone by 4 seconds
    # for chrome_java.
    if not ERRORPRONE_CHECKS_TO_APPLY:
      javac_args += ['-XDshould-stop.ifNoError=FLOW']

  if options.java_version:
    javac_args.extend([
        '-source',
        options.java_version,
        '-target',
        options.java_version,
    ])
  if options.java_version == '1.8':
    # Android's boot jar doesn't contain all java 8 classes.
    options.bootclasspath.append(build_utils.RT_JAR_PATH)

  if options.processors:
    javac_args.extend(['-processor', ','.join(options.processors)])
  else:
    # This effectively disables all annotation processors, even including
    # annotation processors in service provider configuration files named
    # META-INF/. See the following link for reference:
    #     https://docs.oracle.com/en/java/javase/11/tools/javac.html
    javac_args.extend(['-proc:none'])

  if options.bootclasspath:
    javac_args.extend(['-bootclasspath', ':'.join(options.bootclasspath)])

  if options.processorpath:
    javac_args.extend(['-processorpath', ':'.join(options.processorpath)])
  if options.processor_args:
    for arg in options.processor_args:
      javac_args.extend(['-A%s' % arg])

  javac_args.extend(options.javac_arg)

  classpath_inputs = (
      options.bootclasspath + options.classpath + options.processorpath)

  depfile_deps = classpath_inputs
  # Files that are already inputs in GN should go in input_paths.
  input_paths = depfile_deps + options.java_srcjars + java_files
  if options.header_jar:
    input_paths.append(options.header_jar)
  input_paths += [x[0] for x in options.additional_jar_files]

  output_paths = [options.jar_path]
  if not options.enable_errorprone:
    output_paths += [options.jar_path + '.info']

  input_strings = javac_cmd + javac_args + options.classpath + java_files + [
      options.warnings_as_errors, options.jar_info_exclude_globs
  ]

  # Keep md5_check since we plan to use its changes feature to implement a build
  # speed improvement for non-signature compiles: https://crbug.com/1170778
  md5_check.CallAndWriteDepfileIfStale(
      lambda: _OnStaleMd5(options, javac_cmd, javac_args, java_files),
      options,
      depfile_deps=depfile_deps,
      input_paths=input_paths,
      input_strings=input_strings,
      output_paths=output_paths)


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
