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

def _StripGenerics(value):
  """Strips Java generics from a string."""
  nest_level = 0  # How deeply we are nested inside the generics.
  start_index = 0  # Starting index of the last non-generic region.
  out = []
  for i, c in enumerate(value):
    if c == '<':
      if nest_level == 0:
        out.append(value[start_index:i])
      nest_level += 1
    elif c == '>':
      start_index = i + 1
      nest_level -= 1
  out.append(value[start_index:])
  return ''.join(out)

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 'int'
  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 = []
    params = _StripGenerics(params)
    for p in params.split(','):
        items = p.split()
        # Remove @Annotations from parameters.
        while items[0].startswith('@'):
            del items[0]
        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
# ScopedLocalJavaRef.
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 = sizeof(kMethods${JAVA_CLASS})/sizeof(kMethods${JAVA_CLASS}[0]);

  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 = '.Get()'

    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 ('int(' + 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 = 'base::android::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::ScopedLocalJavaRef<' + 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 intptr_t 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).Get()));""")
    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::GetMethod(
      env, ${JAVA_CLASS}_clazz(env),
      base::android::${STATIC}_METHOD,
      "${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:])



class Opitions(object):

  def __init__(self):
    self.ptr_type = 'int'
    self.jni_init_native_name = ''
    self.script_name = GetScriptName()
    self.native_exports = ''
    self.eager_called_by_natives = ''
    self.pure_native_methods = ''
    self.native_exports_optional = ''
    self.includes = ''
    self.optimize_generation = ''
    self.namespace = ''

if __name__ == '__main__':
  """sys.exit(main(sys.argv))"""
  if(len(sys.argv) == 3):
    options = Opitions()
    GenerateJNIHeader(sys.argv[1], sys.argv[2], options)
