#!/usr/bin/env python
# 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.

"""Extracts native methods from a Java file and generates the JNI bindings.
If you change this, please run and update the tests."""

import collections
import errno
import optparse
import os
import re
import string
from string import Template
import subprocess
import sys
import textwrap
import zipfile

CHROMIUM_SRC = os.path.join(
    os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)
BUILD_ANDROID_GYP = os.path.join(
    CHROMIUM_SRC, 'build', 'android', 'gyp')

sys.path.append(BUILD_ANDROID_GYP)

from util import build_utils


class ParseError(Exception):
  """Exception thrown when we can't parse the input file."""

  def __init__(self, description, *context_lines):
    Exception.__init__(self)
    self.description = description
    self.context_lines = context_lines

  def __str__(self):
    context = '\n'.join(self.context_lines)
    return '***\nERROR: %s\n\n%s\n***' % (self.description, context)


class Param(object):
  """Describes a param for a method, either java or native."""

  def __init__(self, **kwargs):
    self.datatype = kwargs['datatype']
    self.name = kwargs['name']


class NativeMethod(object):
  """Describes a C/C++ method that is called by Java code"""

  def __init__(self, **kwargs):
    self.static = kwargs['static']
    self.java_class_name = kwargs['java_class_name']
    self.return_type = kwargs['return_type']
    self.name = kwargs['name']
    self.params = kwargs['params']
    if self.params:
      assert type(self.params) is list
      assert type(self.params[0]) is Param
    if (self.params and
        self.params[0].datatype == kwargs.get('ptr_type', 'int') and
        self.params[0].name.startswith('native')):
      self.type = 'method'
      self.p0_type = self.params[0].name[len('native'):]
      if kwargs.get('native_class_name'):
        self.p0_type = kwargs['native_class_name']
    else:
      self.type = 'function'
    self.method_id_var_name = kwargs.get('method_id_var_name', None)


class CalledByNative(object):
  """Describes a java method exported to c/c++"""

  def __init__(self, **kwargs):
    self.system_class = kwargs['system_class']
    self.unchecked = kwargs['unchecked']
    self.static = kwargs['static']
    self.java_class_name = kwargs['java_class_name']
    self.return_type = kwargs['return_type']
    self.name = kwargs['name']
    self.params = kwargs['params']
    self.method_id_var_name = kwargs.get('method_id_var_name', None)
    self.signature = kwargs.get('signature')
    self.is_constructor = kwargs.get('is_constructor', False)
    self.env_call = GetEnvCall(self.is_constructor, self.static,
                               self.return_type)
    self.static_cast = GetStaticCastForReturnType(self.return_type)


class ConstantField(object):
  def __init__(self, **kwargs):
    self.name = kwargs['name']
    self.value = kwargs['value']


def JavaDataTypeToC(java_type):
  """Returns a C datatype for the given java type."""
  java_pod_type_map = {
      'int': 'jint',
      'byte': 'jbyte',
      'char': 'jchar',
      'short': 'jshort',
      'boolean': 'jboolean',
      'long': 'jlong',
      'double': 'jdouble',
      'float': 'jfloat',
  }
  java_type_map = {
      'void': 'void',
      'String': 'jstring',
      'java/lang/String': 'jstring',
      'java/lang/Class': 'jclass',
  }

  if java_type in java_pod_type_map:
    return java_pod_type_map[java_type]
  elif java_type in java_type_map:
    return java_type_map[java_type]
  elif java_type.endswith('[]'):
    if java_type[:-2] in java_pod_type_map:
      return java_pod_type_map[java_type[:-2]] + 'Array'
    return 'jobjectArray'
  elif java_type.startswith('Class'):
    # Checking just the start of the name, rather than a direct comparison,
    # in order to handle generics.
    return 'jclass'
  else:
    return 'jobject'


def JavaDataTypeToCForCalledByNativeParam(java_type):
  """Returns a C datatype to be when calling from native."""
  if java_type == 'int':
    return 'JniIntWrapper'
  else:
    return JavaDataTypeToC(java_type)


def JavaReturnValueToC(java_type):
  """Returns a valid C return value for the given java type."""
  java_pod_type_map = {
      'int': '0',
      'byte': '0',
      'char': '0',
      'short': '0',
      'boolean': 'false',
      'long': '0',
      'double': '0',
      'float': '0',
      'void': ''
  }
  return java_pod_type_map.get(java_type, 'NULL')


class JniParams(object):
  _imports = []
  _fully_qualified_class = ''
  _package = ''
  _inner_classes = []
  _remappings = []
  _implicit_imports = []

  @staticmethod
  def SetFullyQualifiedClass(fully_qualified_class):
    JniParams._fully_qualified_class = 'L' + fully_qualified_class
    JniParams._package = '/'.join(fully_qualified_class.split('/')[:-1])

  @staticmethod
  def AddAdditionalImport(class_name):
    assert class_name.endswith('.class')
    raw_class_name = class_name[:-len('.class')]
    if '.' in raw_class_name:
      raise SyntaxError('%s cannot be used in @JNIAdditionalImport. '
                        'Only import unqualified outer classes.' % class_name)
    new_import = 'L%s/%s' % (JniParams._package, raw_class_name)
    if new_import in JniParams._imports:
      raise SyntaxError('Do not use JNIAdditionalImport on an already '
                        'imported class: %s' % (new_import.replace('/', '.')))
    JniParams._imports += [new_import]

  @staticmethod
  def ExtractImportsAndInnerClasses(contents):
    if not JniParams._package:
      raise RuntimeError('SetFullyQualifiedClass must be called before '
                         'ExtractImportsAndInnerClasses')
    contents = contents.replace('\n', '')
    re_import = re.compile(r'import.*?(?P<class>\S*?);')
    for match in re.finditer(re_import, contents):
      JniParams._imports += ['L' + match.group('class').replace('.', '/')]

    re_inner = re.compile(r'(class|interface)\s+?(?P<name>\w+?)\W')
    for match in re.finditer(re_inner, contents):
      inner = match.group('name')
      if not JniParams._fully_qualified_class.endswith(inner):
        JniParams._inner_classes += [JniParams._fully_qualified_class + '$' +
                                     inner]

    re_additional_imports = re.compile(
        r'@JNIAdditionalImport\(\s*{?(?P<class_names>.*?)}?\s*\)')
    for match in re.finditer(re_additional_imports, contents):
      for class_name in match.group('class_names').split(','):
        JniParams.AddAdditionalImport(class_name.strip())

  @staticmethod
  def ParseJavaPSignature(signature_line):
    prefix = 'Signature: '
    index = signature_line.find(prefix)
    if index == -1:
      prefix = 'descriptor: '
      index = signature_line.index(prefix)
    return '"%s"' % signature_line[index + len(prefix):]

  @staticmethod
  def JavaToJni(param):
    """Converts a java param into a JNI signature type."""
    pod_param_map = {
        'int': 'I',
        'boolean': 'Z',
        'char': 'C',
        'short': 'S',
        'long': 'J',
        'double': 'D',
        'float': 'F',
        'byte': 'B',
        'void': 'V',
    }
    object_param_list = [
        'Ljava/lang/Boolean',
        'Ljava/lang/Integer',
        'Ljava/lang/Long',
        'Ljava/lang/Object',
        'Ljava/lang/String',
        'Ljava/lang/Class',
    ]

    prefix = ''
    # Array?
    while param[-2:] == '[]':
      prefix += '['
      param = param[:-2]
    # Generic?
    if '<' in param:
      param = param[:param.index('<')]
    if param in pod_param_map:
      return prefix + pod_param_map[param]
    if '/' in param:
      # Coming from javap, use the fully qualified param directly.
      return prefix + 'L' + JniParams.RemapClassName(param) + ';'

    for qualified_name in (object_param_list +
                           [JniParams._fully_qualified_class] +
                           JniParams._inner_classes):
      if (qualified_name.endswith('/' + param) or
          qualified_name.endswith('$' + param.replace('.', '$')) or
          qualified_name == 'L' + param):
        return prefix + JniParams.RemapClassName(qualified_name) + ';'

    # Is it from an import? (e.g. referecing Class from import pkg.Class;
    # note that referencing an inner class Inner from import pkg.Class.Inner
    # is not supported).
    for qualified_name in JniParams._imports:
      if qualified_name.endswith('/' + param):
        # Ensure it's not an inner class.
        components = qualified_name.split('/')
        if len(components) > 2 and components[-2][0].isupper():
          raise SyntaxError('Inner class (%s) can not be imported '
                            'and used by JNI (%s). Please import the outer '
                            'class and use Outer.Inner instead.' %
                            (qualified_name, param))
        return prefix + JniParams.RemapClassName(qualified_name) + ';'

    # Is it an inner class from an outer class import? (e.g. referencing
    # Class.Inner from import pkg.Class).
    if '.' in param:
      components = param.split('.')
      outer = '/'.join(components[:-1])
      inner = components[-1]
      for qualified_name in JniParams._imports:
        if qualified_name.endswith('/' + outer):
          return (prefix + JniParams.RemapClassName(qualified_name) +
                  '$' + inner + ';')
      raise SyntaxError('Inner class (%s) can not be '
                        'used directly by JNI. Please import the outer '
                        'class, probably:\n'
                        'import %s.%s;' %
                        (param, JniParams._package.replace('/', '.'),
                         outer.replace('/', '.')))

    JniParams._CheckImplicitImports(param)

    # Type not found, falling back to same package as this class.
    return (prefix + 'L' +
            JniParams.RemapClassName(JniParams._package + '/' + param) + ';')

  @staticmethod
  def _CheckImplicitImports(param):
    # Ensure implicit imports, such as java.lang.*, are not being treated
    # as being in the same package.
    if not JniParams._implicit_imports:
      # This file was generated from android.jar and lists
      # all classes that are implicitly imported.
      with file(os.path.join(os.path.dirname(sys.argv[0]),
                             'android_jar.classes'), 'r') as f:
        JniParams._implicit_imports = f.readlines()
    for implicit_import in JniParams._implicit_imports:
      implicit_import = implicit_import.strip().replace('.class', '')
      implicit_import = implicit_import.replace('/', '.')
      if implicit_import.endswith('.' + param):
        raise SyntaxError('Ambiguous class (%s) can not be used directly '
                          'by JNI.\nPlease import it, probably:\n\n'
                          'import %s;' %
                          (param, implicit_import))


  @staticmethod
  def Signature(params, returns, wrap):
    """Returns the JNI signature for the given datatypes."""
    items = ['(']
    items += [JniParams.JavaToJni(param.datatype) for param in params]
    items += [')']
    items += [JniParams.JavaToJni(returns)]
    if wrap:
      return '\n' + '\n'.join(['"' + item + '"' for item in items])
    else:
      return '"' + ''.join(items) + '"'

  @staticmethod
  def Parse(params):
    """Parses the params into a list of Param objects."""
    if not params:
      return []
    ret = []
    for p in [p.strip() for p in params.split(',')]:
      items = p.split(' ')
      if 'final' in items:
        items.remove('final')
      param = Param(
          datatype=items[0],
          name=(items[1] if len(items) > 1 else 'p%s' % len(ret)),
      )
      ret += [param]
    return ret

  @staticmethod
  def RemapClassName(class_name):
    """Remaps class names using the jarjar mapping table."""
    for old, new in JniParams._remappings:
      if old.endswith('**') and old[:-2] in class_name:
        return class_name.replace(old[:-2], new, 1)
      if '*' not in old and class_name.endswith(old):
        return class_name.replace(old, new, 1)

    return class_name

  @staticmethod
  def SetJarJarMappings(mappings):
    """Parse jarjar mappings from a string."""
    JniParams._remappings = []
    for line in mappings.splitlines():
      rule = line.split()
      if rule[0] != 'rule':
        continue
      _, src, dest = rule
      src = src.replace('.', '/')
      dest = dest.replace('.', '/')
      if src.endswith('**'):
        src_real_name = src[:-2]
      else:
        assert not '*' in src
        src_real_name = src

      if dest.endswith('@0'):
        JniParams._remappings.append((src, dest[:-2] + src_real_name))
      elif dest.endswith('@1'):
        assert '**' in src
        JniParams._remappings.append((src, dest[:-2]))
      else:
        assert not '@' in dest
        JniParams._remappings.append((src, dest))


def ExtractJNINamespace(contents):
  re_jni_namespace = re.compile('.*?@JNINamespace\("(.*?)"\)')
  m = re.findall(re_jni_namespace, contents)
  if not m:
    return ''
  return m[0]


def ExtractFullyQualifiedJavaClassName(java_file_name, contents):
  re_package = re.compile('.*?package (.*?);')
  matches = re.findall(re_package, contents)
  if not matches:
    raise SyntaxError('Unable to find "package" line in %s' % java_file_name)
  return (matches[0].replace('.', '/') + '/' +
          os.path.splitext(os.path.basename(java_file_name))[0])


def ExtractNatives(contents, ptr_type):
  """Returns a list of dict containing information about a native method."""
  contents = contents.replace('\n', '')
  natives = []
  re_native = re.compile(r'(@NativeClassQualifiedName'
                         '\(\"(?P<native_class_name>.*?)\"\)\s+)?'
                         '(@NativeCall(\(\"(?P<java_class_name>.*?)\"\))\s+)?'
                         '(?P<qualifiers>\w+\s\w+|\w+|\s+)\s*native '
                         '(?P<return_type>\S*) '
                         '(?P<name>native\w+)\((?P<params>.*?)\);')
  for match in re.finditer(re_native, contents):
    native = NativeMethod(
        static='static' in match.group('qualifiers'),
        java_class_name=match.group('java_class_name'),
        native_class_name=match.group('native_class_name'),
        return_type=match.group('return_type'),
        name=match.group('name').replace('native', ''),
        params=JniParams.Parse(match.group('params')),
        ptr_type=ptr_type)
    natives += [native]
  return natives


def GetStaticCastForReturnType(return_type):
  type_map = { 'String' : 'jstring',
               'java/lang/String' : 'jstring',
               'boolean[]': 'jbooleanArray',
               'byte[]': 'jbyteArray',
               'char[]': 'jcharArray',
               'short[]': 'jshortArray',
               'int[]': 'jintArray',
               'long[]': 'jlongArray',
               'float[]': 'jfloatArray',
               'double[]': 'jdoubleArray' }
  ret = type_map.get(return_type, None)
  if ret:
    return ret
  if return_type.endswith('[]'):
    return 'jobjectArray'
  return None


def GetEnvCall(is_constructor, is_static, return_type):
  """Maps the types availabe via env->Call__Method."""
  if is_constructor:
    return 'NewObject'
  env_call_map = {'boolean': 'Boolean',
                  'byte': 'Byte',
                  'char': 'Char',
                  'short': 'Short',
                  'int': 'Int',
                  'long': 'Long',
                  'float': 'Float',
                  'void': 'Void',
                  'double': 'Double',
                  'Object': 'Object',
                 }
  call = env_call_map.get(return_type, 'Object')
  if is_static:
    call = 'Static' + call
  return 'Call' + call + 'Method'


def GetMangledParam(datatype):
  """Returns a mangled identifier for the datatype."""
  if len(datatype) <= 2:
    return datatype.replace('[', 'A')
  ret = ''
  for i in range(1, len(datatype)):
    c = datatype[i]
    if c == '[':
      ret += 'A'
    elif c.isupper() or datatype[i - 1] in ['/', 'L']:
      ret += c.upper()
  return ret


def GetMangledMethodName(name, params, return_type):
  """Returns a mangled method name for the given signature.

     The returned name can be used as a C identifier and will be unique for all
     valid overloads of the same method.

  Args:
     name: string.
     params: list of Param.
     return_type: string.

  Returns:
      A mangled name.
  """
  mangled_items = []
  for datatype in [return_type] + [x.datatype for x in params]:
    mangled_items += [GetMangledParam(JniParams.JavaToJni(datatype))]
  mangled_name = name + '_'.join(mangled_items)
  assert re.match(r'[0-9a-zA-Z_]+', mangled_name)
  return mangled_name


def MangleCalledByNatives(called_by_natives):
  """Mangles all the overloads from the call_by_natives list."""
  method_counts = collections.defaultdict(
      lambda: collections.defaultdict(lambda: 0))
  for called_by_native in called_by_natives:
    java_class_name = called_by_native.java_class_name
    name = called_by_native.name
    method_counts[java_class_name][name] += 1
  for called_by_native in called_by_natives:
    java_class_name = called_by_native.java_class_name
    method_name = called_by_native.name
    method_id_var_name = method_name
    if method_counts[java_class_name][method_name] > 1:
      method_id_var_name = GetMangledMethodName(method_name,
                                                called_by_native.params,
                                                called_by_native.return_type)
    called_by_native.method_id_var_name = method_id_var_name
  return called_by_natives


# Regex to match the JNI return types that should be included in a
# ScopedJavaLocalRef.
RE_SCOPED_JNI_RETURN_TYPES = re.compile('jobject|jclass|jstring|.*Array')

# Regex to match a string like "@CalledByNative public void foo(int bar)".
RE_CALLED_BY_NATIVE = re.compile(
    '@CalledByNative(?P<Unchecked>(Unchecked)*?)(?:\("(?P<annotation>.*)"\))?'
    '\s+(?P<prefix>[\w ]*?)'
    '\s*(?P<return_type>\S+?)'
    '\s+(?P<name>\w+)'
    '\s*\((?P<params>[^\)]*)\)')


def ExtractCalledByNatives(contents):
  """Parses all methods annotated with @CalledByNative.

  Args:
    contents: the contents of the java file.

  Returns:
    A list of dict with information about the annotated methods.
    TODO(bulach): return a CalledByNative object.

  Raises:
    ParseError: if unable to parse.
  """
  called_by_natives = []
  for match in re.finditer(RE_CALLED_BY_NATIVE, contents):
    called_by_natives += [CalledByNative(
        system_class=False,
        unchecked='Unchecked' in match.group('Unchecked'),
        static='static' in match.group('prefix'),
        java_class_name=match.group('annotation') or '',
        return_type=match.group('return_type'),
        name=match.group('name'),
        params=JniParams.Parse(match.group('params')))]
  # Check for any @CalledByNative occurrences that weren't matched.
  unmatched_lines = re.sub(RE_CALLED_BY_NATIVE, '', contents).split('\n')
  for line1, line2 in zip(unmatched_lines, unmatched_lines[1:]):
    if '@CalledByNative' in line1:
      raise ParseError('could not parse @CalledByNative method signature',
                       line1, line2)
  return MangleCalledByNatives(called_by_natives)


class JNIFromJavaP(object):
  """Uses 'javap' to parse a .class file and generate the JNI header file."""

  def __init__(self, contents, options):
    self.contents = contents
    self.namespace = options.namespace
    for line in contents:
      class_name = re.match(
          '.*?(public).*?(class|interface) (?P<class_name>\S+?)( |\Z)',
          line)
      if class_name:
        self.fully_qualified_class = class_name.group('class_name')
        break
    self.fully_qualified_class = self.fully_qualified_class.replace('.', '/')
    # Java 7's javap includes type parameters in output, like HashSet<T>. Strip
    # away the <...> and use the raw class name that Java 6 would've given us.
    self.fully_qualified_class = self.fully_qualified_class.split('<', 1)[0]
    JniParams.SetFullyQualifiedClass(self.fully_qualified_class)
    self.java_class_name = self.fully_qualified_class.split('/')[-1]
    if not self.namespace:
      self.namespace = 'JNI_' + self.java_class_name
    re_method = re.compile('(?P<prefix>.*?)(?P<return_type>\S+?) (?P<name>\w+?)'
                           '\((?P<params>.*?)\)')
    self.called_by_natives = []
    for lineno, content in enumerate(contents[2:], 2):
      match = re.match(re_method, content)
      if not match:
        continue
      self.called_by_natives += [CalledByNative(
          system_class=True,
          unchecked=False,
          static='static' in match.group('prefix'),
          java_class_name='',
          return_type=match.group('return_type').replace('.', '/'),
          name=match.group('name'),
          params=JniParams.Parse(match.group('params').replace('.', '/')),
          signature=JniParams.ParseJavaPSignature(contents[lineno + 1]))]
    re_constructor = re.compile('(.*?)public ' +
                                self.fully_qualified_class.replace('/', '.') +
                                '\((?P<params>.*?)\)')
    for lineno, content in enumerate(contents[2:], 2):
      match = re.match(re_constructor, content)
      if not match:
        continue
      self.called_by_natives += [CalledByNative(
          system_class=True,
          unchecked=False,
          static=False,
          java_class_name='',
          return_type=self.fully_qualified_class,
          name='Constructor',
          params=JniParams.Parse(match.group('params').replace('.', '/')),
          signature=JniParams.ParseJavaPSignature(contents[lineno + 1]),
          is_constructor=True)]
    self.called_by_natives = MangleCalledByNatives(self.called_by_natives)

    self.constant_fields = []
    re_constant_field = re.compile('.*?public static final int (?P<name>.*?);')
    re_constant_field_value = re.compile(
        '.*?Constant(Value| value): int (?P<value>(-*[0-9]+)?)')
    for lineno, content in enumerate(contents[2:], 2):
      match = re.match(re_constant_field, content)
      if not match:
        continue
      value = re.match(re_constant_field_value, contents[lineno + 2])
      if not value:
        value = re.match(re_constant_field_value, contents[lineno + 3])
      if value:
        self.constant_fields.append(
            ConstantField(name=match.group('name'),
                          value=value.group('value')))

    self.inl_header_file_generator = InlHeaderFileGenerator(
        self.namespace, self.fully_qualified_class, [],
        self.called_by_natives, self.constant_fields, options)

  def GetContent(self):
    return self.inl_header_file_generator.GetContent()

  @staticmethod
  def CreateFromClass(class_file, options):
    class_name = os.path.splitext(os.path.basename(class_file))[0]
    p = subprocess.Popen(args=[options.javap, '-c', '-verbose',
                               '-s', class_name],
                         cwd=os.path.dirname(class_file),
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    stdout, _ = p.communicate()
    jni_from_javap = JNIFromJavaP(stdout.split('\n'), options)
    return jni_from_javap


class JNIFromJavaSource(object):
  """Uses the given java source file to generate the JNI header file."""

  # Match single line comments, multiline comments, character literals, and
  # double-quoted strings.
  _comment_remover_regex = re.compile(
      r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
      re.DOTALL | re.MULTILINE)

  def __init__(self, contents, fully_qualified_class, options):
    contents = self._RemoveComments(contents)
    JniParams.SetFullyQualifiedClass(fully_qualified_class)
    JniParams.ExtractImportsAndInnerClasses(contents)
    jni_namespace = ExtractJNINamespace(contents) or options.namespace
    natives = ExtractNatives(contents, options.ptr_type)
    called_by_natives = ExtractCalledByNatives(contents)
    if len(natives) == 0 and len(called_by_natives) == 0:
      raise SyntaxError('Unable to find any JNI methods for %s.' %
                        fully_qualified_class)
    inl_header_file_generator = InlHeaderFileGenerator(
        jni_namespace, fully_qualified_class, natives, called_by_natives,
        [], options)
    self.content = inl_header_file_generator.GetContent()

  @classmethod
  def _RemoveComments(cls, contents):
    # We need to support both inline and block comments, and we need to handle
    # strings that contain '//' or '/*'.
    # TODO(bulach): This is a bit hacky. It would be cleaner to use a real Java
    # parser. Maybe we could ditch JNIFromJavaSource and just always use
    # JNIFromJavaP; or maybe we could rewrite this script in Java and use APT.
    # http://code.google.com/p/chromium/issues/detail?id=138941
    def replacer(match):
      # Replace matches that are comments with nothing; return literals/strings
      # unchanged.
      s = match.group(0)
      if s.startswith('/'):
        return ''
      else:
        return s
    return cls._comment_remover_regex.sub(replacer, contents)

  def GetContent(self):
    return self.content

  @staticmethod
  def CreateFromFile(java_file_name, options):
    contents = file(java_file_name).read()
    fully_qualified_class = ExtractFullyQualifiedJavaClassName(java_file_name,
                                                               contents)
    return JNIFromJavaSource(contents, fully_qualified_class, options)


class InlHeaderFileGenerator(object):
  """Generates an inline header file for JNI integration."""

  def __init__(self, namespace, fully_qualified_class, natives,
               called_by_natives, constant_fields, options):
    self.namespace = namespace
    self.fully_qualified_class = fully_qualified_class
    self.class_name = self.fully_qualified_class.split('/')[-1]
    self.natives = natives
    self.called_by_natives = called_by_natives
    self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI'
    self.constant_fields = constant_fields
    self.options = options
    self.init_native = self.ExtractInitNative(options)

  def ExtractInitNative(self, options):
    for native in self.natives:
      if options.jni_init_native_name == 'native' + native.name:
        self.natives.remove(native)
        return native
    return None

  def GetContent(self):
    """Returns the content of the JNI binding file."""
    template = Template("""\
// 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.


// This file is autogenerated by
//     ${SCRIPT_NAME}
// For
//     ${FULLY_QUALIFIED_CLASS}

#ifndef ${HEADER_GUARD}
#define ${HEADER_GUARD}

#include <jni.h>

${INCLUDES}

#include "base/android/jni_int_wrapper.h"

// Step 1: forward declarations.
namespace {
$CLASS_PATH_DEFINITIONS
$METHOD_ID_DEFINITIONS
}  // namespace

$OPEN_NAMESPACE
$FORWARD_DECLARATIONS

$CONSTANT_FIELDS

// Step 2: method stubs.
$METHOD_STUBS

// Step 3: RegisterNatives.
$JNI_NATIVE_METHODS
$REGISTER_NATIVES
$CLOSE_NAMESPACE
$JNI_REGISTER_NATIVES
#endif  // ${HEADER_GUARD}
""")
    values = {
        'SCRIPT_NAME': self.options.script_name,
        'FULLY_QUALIFIED_CLASS': self.fully_qualified_class,
        'CLASS_PATH_DEFINITIONS': self.GetClassPathDefinitionsString(),
        'METHOD_ID_DEFINITIONS': self.GetMethodIDDefinitionsString(),
        'FORWARD_DECLARATIONS': self.GetForwardDeclarationsString(),
        'CONSTANT_FIELDS': self.GetConstantFieldsString(),
        'METHOD_STUBS': self.GetMethodStubsString(),
        'OPEN_NAMESPACE': self.GetOpenNamespaceString(),
        'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(),
        'REGISTER_NATIVES': self.GetRegisterNativesString(),
        'CLOSE_NAMESPACE': self.GetCloseNamespaceString(),
        'HEADER_GUARD': self.header_guard,
        'INCLUDES': self.GetIncludesString(),
        'JNI_REGISTER_NATIVES': self.GetJNIRegisterNativesString()
    }
    return WrapOutput(template.substitute(values))

  def GetClassPathDefinitionsString(self):
    ret = []
    ret += [self.GetClassPathDefinitions()]
    return '\n'.join(ret)

  def GetMethodIDDefinitionsString(self):
    """Returns the definition of method ids for the called by native methods."""
    if not self.options.eager_called_by_natives:
      return ''
    template = Template("""\
jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
    ret = []
    for called_by_native in self.called_by_natives:
      values = {
          'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
          'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
      }
      ret += [template.substitute(values)]
    return '\n'.join(ret)

  def GetForwardDeclarationsString(self):
    ret = []
    for native in self.natives:
      if native.type != 'method':
        ret += [self.GetForwardDeclaration(native)]
    if self.options.native_exports and ret:
      return '\nextern "C" {\n' + "\n".join(ret) + '\n};  // extern "C"'
    return '\n'.join(ret)

  def GetConstantFieldsString(self):
    if not self.constant_fields:
      return ''
    ret = ['enum Java_%s_constant_fields {' % self.class_name]
    for c in self.constant_fields:
      ret += ['  %s = %s,' % (c.name, c.value)]
    ret += ['};']
    return '\n'.join(ret)

  def GetMethodStubsString(self):
    """Returns the code corresponding to method stubs."""
    ret = []
    for native in self.natives:
      if native.type == 'method':
        ret += [self.GetNativeMethodStubString(native)]
    if self.options.eager_called_by_natives:
      ret += self.GetEagerCalledByNativeMethodStubs()
    else:
      ret += self.GetLazyCalledByNativeMethodStubs()

    if self.options.native_exports and ret:
      return '\nextern "C" {\n' + "\n".join(ret) + '\n};  // extern "C"'
    return '\n'.join(ret)

  def GetLazyCalledByNativeMethodStubs(self):
    return [self.GetLazyCalledByNativeMethodStub(called_by_native)
            for called_by_native in self.called_by_natives]

  def GetEagerCalledByNativeMethodStubs(self):
    ret = []
    if self.called_by_natives:
      ret += ['namespace {']
      for called_by_native in self.called_by_natives:
        ret += [self.GetEagerCalledByNativeMethodStub(called_by_native)]
      ret += ['}  // namespace']
    return ret

  def GetIncludesString(self):
    if not self.options.includes:
      return ''
    includes = self.options.includes.split(',')
    return '\n'.join('#include "%s"' % x for x in includes)

  def GetKMethodsString(self, clazz):
    ret = []
    for native in self.natives:
      if (native.java_class_name == clazz or
          (not native.java_class_name and clazz == self.class_name)):
        ret += [self.GetKMethodArrayEntry(native)]
    return '\n'.join(ret)

  def SubstituteNativeMethods(self, template):
    """Substitutes JAVA_CLASS and KMETHODS in the provided template."""
    ret = []
    all_classes = self.GetUniqueClasses(self.natives)
    all_classes[self.class_name] = self.fully_qualified_class
    for clazz in all_classes:
      kmethods = self.GetKMethodsString(clazz)
      if kmethods:
        values = {'JAVA_CLASS': clazz,
                  'KMETHODS': kmethods}
        ret += [template.substitute(values)]
    if not ret: return ''
    return '\n' + '\n'.join(ret)

  def GetJNINativeMethodsString(self):
    """Returns the implementation of the array of native methods."""
    if self.options.native_exports and not self.options.native_exports_optional:
      return ''
    template = Template("""\
static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
${KMETHODS}
};
""")
    return self.SubstituteNativeMethods(template)

  def GetRegisterCalledByNativesImplString(self):
    """Returns the code for registering the called by native methods."""
    if not self.options.eager_called_by_natives:
      return ''
    template = Template("""\
  g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = ${GET_METHOD_ID_IMPL}
  if (g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} == NULL) {
    return false;
  }
    """)
    ret = []
    for called_by_native in self.called_by_natives:
      values = {
          'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
          'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
          'GET_METHOD_ID_IMPL': self.GetMethodIDImpl(called_by_native),
      }
      ret += [template.substitute(values)]
    return '\n'.join(ret)

  def GetRegisterNativesString(self):
    """Returns the code for RegisterNatives."""
    template = Template("""\
${REGISTER_NATIVES_SIGNATURE} {
${EARLY_EXIT}
${CLASSES}
${NATIVES}
${CALLED_BY_NATIVES}
  return true;
}
""")
    signature = 'static bool RegisterNativesImpl(JNIEnv* env'
    if self.init_native:
      signature += ', jclass clazz)'
    else:
      signature += ')'

    early_exit = ''
    if self.options.native_exports_optional:
      early_exit = """\
  if (base::android::IsManualJniRegistrationDisabled()) return true;
"""

    natives = self.GetRegisterNativesImplString()
    called_by_natives = self.GetRegisterCalledByNativesImplString()
    values = {'REGISTER_NATIVES_SIGNATURE': signature,
              'EARLY_EXIT': early_exit,
              'CLASSES': self.GetFindClasses(),
              'NATIVES': natives,
              'CALLED_BY_NATIVES': called_by_natives,
             }
    return template.substitute(values)

  def GetRegisterNativesImplString(self):
    """Returns the shared implementation for RegisterNatives."""
    if self.options.native_exports and not self.options.native_exports_optional:
      return ''

    template = Template("""\
  const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});

  if (env->RegisterNatives(${JAVA_CLASS}_clazz(env),
                           kMethods${JAVA_CLASS},
                           kMethods${JAVA_CLASS}Size) < 0) {
    jni_generator::HandleRegistrationError(
        env, ${JAVA_CLASS}_clazz(env), __FILE__);
    return false;
  }
""")
    return self.SubstituteNativeMethods(template)

  def GetJNIRegisterNativesString(self):
    """Returns the implementation for the JNI registration of native methods."""
    if not self.init_native:
      return ''

    template = Template("""\
extern "C" JNIEXPORT bool JNICALL
Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
  return ${NAMESPACE}RegisterNativesImpl(env, clazz);
}
""")

    if self.options.native_exports:
      java_name = JniParams.RemapClassName(self.fully_qualified_class)
      java_name = java_name.replace('_', '_1').replace('/', '_')
    else:
      java_name = self.fully_qualified_class.replace('/', '_')

    namespace = ''
    if self.namespace:
      namespace = self.namespace + '::'
    values = {'FULLY_QUALIFIED_CLASS': java_name,
              'INIT_NATIVE_NAME': 'native' + self.init_native.name,
              'NAMESPACE': namespace,
              'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString()
             }
    return template.substitute(values)

  def GetOpenNamespaceString(self):
    if self.namespace:
      all_namespaces = ['namespace %s {' % ns
                        for ns in self.namespace.split('::')]
      return '\n'.join(all_namespaces)
    return ''

  def GetCloseNamespaceString(self):
    if self.namespace:
      all_namespaces = ['}  // namespace %s' % ns
                        for ns in self.namespace.split('::')]
      all_namespaces.reverse()
      return '\n'.join(all_namespaces) + '\n'
    return ''

  def GetJNIFirstParam(self, native):
    ret = []
    if native.type == 'method':
      ret = ['jobject jcaller']
    elif native.type == 'function':
      if native.static:
        ret = ['jclass jcaller']
      else:
        ret = ['jobject jcaller']
    return ret

  def GetParamsInDeclaration(self, native):
    """Returns the params for the stub declaration.

    Args:
      native: the native dictionary describing the method.

    Returns:
      A string containing the params.
    """
    return ',\n    '.join(self.GetJNIFirstParam(native) +
                          [JavaDataTypeToC(param.datatype) + ' ' +
                           param.name
                           for param in native.params])

  def GetCalledByNativeParamsInDeclaration(self, called_by_native):
    return ',\n    '.join([
        JavaDataTypeToCForCalledByNativeParam(param.datatype) + ' ' +
        param.name
        for param in called_by_native.params])

  def GetStubName(self, native):
    """Return the name of the stub function for this native method.

    Args:
      native: the native dictionary describing the method.

    Returns:
      A string with the stub function name. For native exports mode this is the
      Java_* symbol name required by the JVM; otherwise it is just the name of
      the native method itself.
    """
    if self.options.native_exports:
      template = Template("Java_${JAVA_NAME}_native${NAME}")

      java_name = JniParams.RemapClassName(self.fully_qualified_class)
      java_name = java_name.replace('_', '_1').replace('/', '_')
      if native.java_class_name:
        java_name += '_00024' + native.java_class_name

      values = {'NAME': native.name,
                'JAVA_NAME': java_name}
      return template.substitute(values)
    else:
      return native.name

  def GetForwardDeclaration(self, native):
    template_str = """
static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
"""
    if self.options.native_exports:
      template_str += """
__attribute__((visibility("default")))
${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) {
  return ${NAME}(${PARAMS_IN_CALL});
}
"""
    template = Template(template_str)
    params_in_call = []
    if not self.options.pure_native_methods:
      params_in_call = ['env', 'jcaller']
    params_in_call = ', '.join(params_in_call + [p.name for p in native.params])

    values = {'RETURN': JavaDataTypeToC(native.return_type),
              'NAME': native.name,
              'PARAMS': self.GetParamsInDeclaration(native),
              'PARAMS_IN_CALL': params_in_call,
              'STUB_NAME': self.GetStubName(native)}
    return template.substitute(values)

  def GetNativeMethodStubString(self, native):
    """Returns stubs for native methods."""
    if self.options.native_exports:
      template_str = """\
__attribute__((visibility("default")))
${RETURN} ${STUB_NAME}(JNIEnv* env,
    ${PARAMS_IN_DECLARATION}) {"""
    else:
      template_str = """\
static ${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {"""
    template_str += """
  ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
  CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
  return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
}
"""

    template = Template(template_str)
    params = []
    if not self.options.pure_native_methods:
      params = ['env', 'jcaller']
    params_in_call = ', '.join(params + [p.name for p in native.params[1:]])

    return_type = JavaDataTypeToC(native.return_type)
    optional_error_return = JavaReturnValueToC(native.return_type)
    if optional_error_return:
      optional_error_return = ', ' + optional_error_return
    post_call = ''
    if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
      post_call = '.Release()'

    values = {
        'RETURN': return_type,
        'OPTIONAL_ERROR_RETURN': optional_error_return,
        'NAME': native.name,
        'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
        'PARAM0_NAME': native.params[0].name,
        'P0_TYPE': native.p0_type,
        'PARAMS_IN_CALL': params_in_call,
        'POST_CALL': post_call,
        'STUB_NAME': self.GetStubName(native),
    }
    return template.substitute(values)

  def GetArgument(self, param):
    return ('as_jint(' + param.name + ')'
            if param.datatype == 'int' else param.name)

  def GetArgumentsInCall(self, params):
    """Return a string of arguments to call from native into Java"""
    return [self.GetArgument(p) for p in params]

  def GetCalledByNativeValues(self, called_by_native):
    """Fills in necessary values for the CalledByNative methods."""
    java_class = called_by_native.java_class_name or self.class_name
    if called_by_native.static or called_by_native.is_constructor:
      first_param_in_declaration = ''
      first_param_in_call = ('%s_clazz(env)' % java_class)
    else:
      first_param_in_declaration = ', jobject obj'
      first_param_in_call = 'obj'
    params_in_declaration = self.GetCalledByNativeParamsInDeclaration(
        called_by_native)
    if params_in_declaration:
      params_in_declaration = ', ' + params_in_declaration
    params_in_call = ', '.join(self.GetArgumentsInCall(called_by_native.params))
    if params_in_call:
      params_in_call = ', ' + params_in_call
    pre_call = ''
    post_call = ''
    if called_by_native.static_cast:
      pre_call = 'static_cast<%s>(' % called_by_native.static_cast
      post_call = ')'
    check_exception = ''
    if not called_by_native.unchecked:
      check_exception = 'jni_generator::CheckException(env);'
    return_type = JavaDataTypeToC(called_by_native.return_type)
    optional_error_return = JavaReturnValueToC(called_by_native.return_type)
    if optional_error_return:
      optional_error_return = ', ' + optional_error_return
    return_declaration = ''
    return_clause = ''
    if return_type != 'void':
      pre_call = ' ' + pre_call
      return_declaration = return_type + ' ret ='
      if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
        return_type = 'base::android::ScopedJavaLocalRef<' + return_type + '>'
        return_clause = 'return ' + return_type + '(env, ret);'
      else:
        return_clause = 'return ret;'
    return {
        'JAVA_CLASS': java_class,
        'RETURN_TYPE': return_type,
        'OPTIONAL_ERROR_RETURN': optional_error_return,
        'RETURN_DECLARATION': return_declaration,
        'RETURN_CLAUSE': return_clause,
        'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration,
        'PARAMS_IN_DECLARATION': params_in_declaration,
        'PRE_CALL': pre_call,
        'POST_CALL': post_call,
        'ENV_CALL': called_by_native.env_call,
        'FIRST_PARAM_IN_CALL': first_param_in_call,
        'PARAMS_IN_CALL': params_in_call,
        'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
        'CHECK_EXCEPTION': check_exception,
        'GET_METHOD_ID_IMPL': self.GetMethodIDImpl(called_by_native)
    }

  def GetEagerCalledByNativeMethodStub(self, called_by_native):
    """Returns the implementation of the called by native method."""
    template = Template("""
static ${RETURN_TYPE} ${METHOD_ID_VAR_NAME}(\
JNIEnv* env${FIRST_PARAM_IN_DECLARATION}${PARAMS_IN_DECLARATION}) {
  ${RETURN_DECLARATION}${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL},
      g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}${PARAMS_IN_CALL})${POST_CALL};
  ${RETURN_CLAUSE}
}""")
    values = self.GetCalledByNativeValues(called_by_native)
    return template.substitute(values)

  def GetLazyCalledByNativeMethodStub(self, called_by_native):
    """Returns a string."""
    function_signature_template = Template("""\
static ${RETURN_TYPE} Java_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}(\
JNIEnv* env${FIRST_PARAM_IN_DECLARATION}${PARAMS_IN_DECLARATION})""")
    function_header_template = Template("""\
${FUNCTION_SIGNATURE} {""")
    function_header_with_unused_template = Template("""\
${FUNCTION_SIGNATURE} __attribute__ ((unused));
${FUNCTION_SIGNATURE} {""")
    template = Template("""
static base::subtle::AtomicWord g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0;
${FUNCTION_HEADER}
  /* Must call RegisterNativesImpl()  */
  CHECK_CLAZZ(env, ${FIRST_PARAM_IN_CALL},
      ${JAVA_CLASS}_clazz(env)${OPTIONAL_ERROR_RETURN});
  jmethodID method_id =
    ${GET_METHOD_ID_IMPL}
  ${RETURN_DECLARATION}
     ${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL},
          method_id${PARAMS_IN_CALL})${POST_CALL};
  ${CHECK_EXCEPTION}
  ${RETURN_CLAUSE}
}""")
    values = self.GetCalledByNativeValues(called_by_native)
    values['FUNCTION_SIGNATURE'] = (
        function_signature_template.substitute(values))
    if called_by_native.system_class:
      values['FUNCTION_HEADER'] = (
          function_header_with_unused_template.substitute(values))
    else:
      values['FUNCTION_HEADER'] = function_header_template.substitute(values)
    return template.substitute(values)

  def GetKMethodArrayEntry(self, native):
    template = Template('    { "native${NAME}", ${JNI_SIGNATURE}, ' +
                        'reinterpret_cast<void*>(${STUB_NAME}) },')
    values = {'NAME': native.name,
              'JNI_SIGNATURE': JniParams.Signature(native.params,
                                                   native.return_type,
                                                   True),
              'STUB_NAME': self.GetStubName(native)}
    return template.substitute(values)

  def GetUniqueClasses(self, origin):
    ret = {self.class_name: self.fully_qualified_class}
    for entry in origin:
      class_name = self.class_name
      jni_class_path = self.fully_qualified_class
      if entry.java_class_name:
        class_name = entry.java_class_name
        jni_class_path = self.fully_qualified_class + '$' + class_name
      ret[class_name] = jni_class_path
    return ret

  def GetClassPathDefinitions(self):
    """Returns the ClassPath constants."""
    ret = []
    template = Template("""\
const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""")
    native_classes = self.GetUniqueClasses(self.natives)
    called_by_native_classes = self.GetUniqueClasses(self.called_by_natives)
    if self.options.native_exports:
      all_classes = called_by_native_classes
    else:
      all_classes = native_classes
      all_classes.update(called_by_native_classes)

    for clazz in all_classes:
      values = {
          'JAVA_CLASS': clazz,
          'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]),
      }
      ret += [template.substitute(values)]
    ret += ''

    class_getter_methods = []
    if self.options.native_exports:
      template = Template("""\
// Leaking this jclass as we cannot use LazyInstance from some threads.
base::subtle::AtomicWord g_${JAVA_CLASS}_clazz __attribute__((unused)) = 0;
#define ${JAVA_CLASS}_clazz(env) \
base::android::LazyGetClass(env, k${JAVA_CLASS}ClassPath, \
&g_${JAVA_CLASS}_clazz)""")
    else:
      template = Template("""\
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_${JAVA_CLASS}_clazz = NULL;
#define ${JAVA_CLASS}_clazz(env) g_${JAVA_CLASS}_clazz""")

    for clazz in called_by_native_classes:
      values = {
          'JAVA_CLASS': clazz,
      }
      ret += [template.substitute(values)]

    return '\n'.join(ret)

  def GetFindClasses(self):
    """Returns the imlementation of FindClass for all known classes."""
    if self.init_native:
      if self.options.native_exports:
        template = Template("""\
  base::subtle::Release_Store(&g_${JAVA_CLASS}_clazz,
      static_cast<base::subtle::AtomicWord>(env->NewWeakGlobalRef(clazz));""")
      else:
        template = Template("""\
  g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""")
    else:
      if self.options.native_exports:
        return '\n'
      template = Template("""\
  g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""")
    ret = []
    for clazz in self.GetUniqueClasses(self.called_by_natives):
      values = {'JAVA_CLASS': clazz}
      ret += [template.substitute(values)]
    return '\n'.join(ret)

  def GetMethodIDImpl(self, called_by_native):
    """Returns the implementation of GetMethodID."""
    if self.options.eager_called_by_natives:
      template = Template("""\
env->Get${STATIC_METHOD_PART}MethodID(
      ${JAVA_CLASS}_clazz(env),
      "${JNI_NAME}", ${JNI_SIGNATURE});""")
    else:
      template = Template("""\
  base::android::MethodID::LazyGet<
      base::android::MethodID::TYPE_${STATIC}>(
      env, ${JAVA_CLASS}_clazz(env),
      "${JNI_NAME}",
      ${JNI_SIGNATURE},
      &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME});
""")
    jni_name = called_by_native.name
    jni_return_type = called_by_native.return_type
    if called_by_native.is_constructor:
      jni_name = '<init>'
      jni_return_type = 'void'
    if called_by_native.signature:
      signature = called_by_native.signature
    else:
      signature = JniParams.Signature(called_by_native.params,
                                      jni_return_type,
                                      True)
    values = {
        'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
        'JNI_NAME': jni_name,
        'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
        'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE',
        'STATIC_METHOD_PART': 'Static' if called_by_native.static else '',
        'JNI_SIGNATURE': signature,
    }
    return template.substitute(values)


def WrapOutput(output):
  ret = []
  for line in output.splitlines():
    # Do not wrap lines under 80 characters or preprocessor directives.
    if len(line) < 80 or line.lstrip()[:1] == '#':
      stripped = line.rstrip()
      if len(ret) == 0 or len(ret[-1]) or len(stripped):
        ret.append(stripped)
    else:
      first_line_indent = ' ' * (len(line) - len(line.lstrip()))
      subsequent_indent =  first_line_indent + ' ' * 4
      if line.startswith('//'):
        subsequent_indent = '//' + subsequent_indent
      wrapper = textwrap.TextWrapper(width=80,
                                     subsequent_indent=subsequent_indent,
                                     break_long_words=False)
      ret += [wrapped.rstrip() for wrapped in wrapper.wrap(line)]
  ret += ['']
  return '\n'.join(ret)


def ExtractJarInputFile(jar_file, input_file, out_dir):
  """Extracts input file from jar and returns the filename.

  The input file is extracted to the same directory that the generated jni
  headers will be placed in.  This is passed as an argument to script.

  Args:
    jar_file: the jar file containing the input files to extract.
    input_files: the list of files to extract from the jar file.
    out_dir: the name of the directories to extract to.

  Returns:
    the name of extracted input file.
  """
  jar_file = zipfile.ZipFile(jar_file)

  out_dir = os.path.join(out_dir, os.path.dirname(input_file))
  try:
    os.makedirs(out_dir)
  except OSError as e:
    if e.errno != errno.EEXIST:
      raise
  extracted_file_name = os.path.join(out_dir, os.path.basename(input_file))
  with open(extracted_file_name, 'w') as outfile:
    outfile.write(jar_file.read(input_file))

  return extracted_file_name


def GenerateJNIHeader(input_file, output_file, options):
  try:
    if os.path.splitext(input_file)[1] == '.class':
      jni_from_javap = JNIFromJavaP.CreateFromClass(input_file, options)
      content = jni_from_javap.GetContent()
    else:
      jni_from_java_source = JNIFromJavaSource.CreateFromFile(
          input_file, options)
      content = jni_from_java_source.GetContent()
  except ParseError, e:
    print e
    sys.exit(1)
  if output_file:
    if not os.path.exists(os.path.dirname(os.path.abspath(output_file))):
      os.makedirs(os.path.dirname(os.path.abspath(output_file)))
    if options.optimize_generation and os.path.exists(output_file):
      with file(output_file, 'r') as f:
        existing_content = f.read()
        if existing_content == content:
          return
    with file(output_file, 'w') as f:
      f.write(content)
  else:
    print output


def GetScriptName():
  script_components = os.path.abspath(sys.argv[0]).split(os.path.sep)
  base_index = 0
  for idx, value in enumerate(script_components):
    if value == 'base' or value == 'third_party':
      base_index = idx
      break
  return os.sep.join(script_components[base_index:])


def main(argv):
  usage = """usage: %prog [OPTIONS]
This script will parse the given java source code extracting the native
declarations and print the header file to stdout (or a file).
See SampleForTests.java for more details.
  """
  option_parser = optparse.OptionParser(usage=usage)
  build_utils.AddDepfileOption(option_parser)

  option_parser.add_option('-j', '--jar_file', dest='jar_file',
                           help='Extract the list of input files from'
                           ' a specified jar file.'
                           ' Uses javap to extract the methods from a'
                           ' pre-compiled class. --input should point'
                           ' to pre-compiled Java .class files.')
  option_parser.add_option('-n', dest='namespace',
                           help='Uses as a namespace in the generated header '
                           'instead of the javap class name, or when there is '
                           'no JNINamespace annotation in the java source.')
  option_parser.add_option('--input_file',
                           help='Single input file name. The output file name '
                           'will be derived from it. Must be used with '
                           '--output_dir.')
  option_parser.add_option('--output_dir',
                           help='The output directory. Must be used with '
                           '--input')
  option_parser.add_option('--optimize_generation', type="int",
                           default=0, help='Whether we should optimize JNI '
                           'generation by not regenerating files if they have '
                           'not changed.')
  option_parser.add_option('--jarjar',
                           help='Path to optional jarjar rules file.')
  option_parser.add_option('--script_name', default=GetScriptName(),
                           help='The name of this script in the generated '
                           'header.')
  option_parser.add_option('--includes',
                           help='The comma-separated list of header files to '
                           'include in the generated header.')
  option_parser.add_option('--pure_native_methods',
                           action='store_true', dest='pure_native_methods',
                           help='When true, the native methods will be called '
                           'without any JNI-specific arguments.')
  option_parser.add_option('--ptr_type', default='int',
                           type='choice', choices=['int', 'long'],
                           help='The type used to represent native pointers in '
                           'Java code. For 32-bit, use int; '
                           'for 64-bit, use long.')
  option_parser.add_option('--jni_init_native_name', default='',
                           help='The name of the JNI registration method that '
                           'is used to initialize all native methods. If a '
                           'method with this name is not present in the Java '
                           'source file, setting this option is a no-op. When '
                           'a method with this name is found however, the '
                           'naming convention Java_<packageName>_<className> '
                           'will limit the initialization to only the '
                           'top-level class.')
  option_parser.add_option('--eager_called_by_natives',
                           action='store_true', dest='eager_called_by_natives',
                           help='When true, the called-by-native methods will '
                           'be initialized in a non-atomic way.')
  option_parser.add_option('--cpp', default='cpp',
                           help='The path to cpp command.')
  option_parser.add_option('--javap', default='javap',
                           help='The path to javap command.')
  option_parser.add_option('--native_exports', action='store_true',
                           help='Native method registration through .so '
                           'exports.')
  option_parser.add_option('--native_exports_optional', action='store_true',
                           help='Support both explicit and native method'
                           'registration.')
  options, args = option_parser.parse_args(argv)
  if options.native_exports_optional:
    options.native_exports = True
  if options.jar_file:
    input_file = ExtractJarInputFile(options.jar_file, options.input_file,
                                     options.output_dir)
  elif options.input_file:
    input_file = options.input_file
  else:
    option_parser.print_help()
    print '\nError: Must specify --jar_file or --input_file.'
    return 1
  output_file = None
  if options.output_dir:
    root_name = os.path.splitext(os.path.basename(input_file))[0]
    output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
  if options.jarjar:
    with open(options.jarjar) as f:
      JniParams.SetJarJarMappings(f.read())
  GenerateJNIHeader(input_file, output_file, options)

  if options.depfile:
    build_utils.WriteDepfile(
        options.depfile,
        build_utils.GetPythonDependencies())


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