// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The java package takes the result of an AST traversal by the
// importers package and queries the java command for the type
// information for the referenced Java classes and interfaces.
//
// It is the of go/types for Java types and is used by the bind
// package to generate Go wrappers for Java API on Android.
package java

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"os/exec"
	"reflect"
	"strings"
	"unicode"
	"unicode/utf8"

	"golang.org/x/mobile/internal/importers"
)

// Class is the bind representation of a Java class or
// interface.
// Use Import to convert class references to Class.
type Class struct {
	// "java.pkg.Class.Inner"
	Name string
	// "java.pkg.Class$Inner"
	FindName string
	// JNI mangled name
	JNIName string
	// "Inner"
	PkgName string
	Funcs   []*FuncSet
	Methods []*FuncSet
	// funcMap maps function names.
	funcMap map[string]*FuncSet
	// FuncMap maps method names.
	methodMap map[string]*FuncSet
	// All methods, including methods from
	// supers.
	AllMethods []*FuncSet
	Vars       []*Var
	Supers     []string
	Final      bool
	Abstract   bool
	Interface  bool
	Throwable  bool
	// Whether the class has a no-arg constructor
	HasNoArgCon bool
}

// FuncSet is the set of overloaded variants of a function.
// If the function is not overloaded, its FuncSet contains
// one entry.
type FuncSet struct {
	Name   string
	GoName string
	Funcs  []*Func
	CommonSig
}

// CommonSig is a signature compatible with every
// overloaded variant of a FuncSet.
type CommonSig struct {
	// Variadic is set if the signature covers variants
	// with varying number of parameters.
	Variadic bool
	// HasRet is true if at least one variant returns a
	// value.
	HasRet bool
	Throws bool
	Params []*Type
	Ret    *Type
}

// Func is a Java static function or method or constructor.
type Func struct {
	FuncSig
	ArgDesc string
	// Mangled JNI name
	JNIName     string
	Static      bool
	Abstract    bool
	Final       bool
	Public      bool
	Constructor bool
	Params      []*Type
	Ret         *Type
	Decl        string
	Throws      string
}

// FuncSig uniquely identifies a Java Func.
type FuncSig struct {
	Name string
	// The method descriptor, in JNI format.
	Desc string
}

// Var is a Java member variable.
type Var struct {
	Name   string
	Static bool
	Final  bool
	Val    string
	Type   *Type
}

// Type is a Java type.
type Type struct {
	Kind  TypeKind
	Class string
	Elem  *Type
}

type TypeKind int

type Importer struct {
	Bootclasspath string
	Classpath     string
	// JavaPkg is java package name for generated classes.
	JavaPkg string

	clsMap map[string]*Class
}

// funcRef is a reference to a Java function (static method).
// It is used as a key to filter unused Java functions.
type funcRef struct {
	clsName string
	goName  string
}

type errClsNotFound struct {
	name string
}

const (
	Int TypeKind = iota
	Boolean
	Short
	Char
	Byte
	Long
	Float
	Double
	String
	Array
	Object
)

func (e *errClsNotFound) Error() string {
	return "class not found: " + e.name
}

// IsAvailable returns whether the required tools are available for
// Import to work. In particular, IsAvailable checks the existence
// of the javap binary.
func IsAvailable() bool {
	_, err := javapPath()
	return err == nil
}

func javapPath() (string, error) {
	return exec.LookPath("javap")
}

// Import returns Java Class descriptors for a list of references.
//
// The javap command from the Java SDK is used to dump
// class information. Its output looks like this:
//
// Compiled from "System.java"
// public final class java.lang.System {
//   public static final java.io.InputStream in;
//     descriptor: Ljava/io/InputStream;
//   public static final java.io.PrintStream out;
//     descriptor: Ljava/io/PrintStream;
//   public static final java.io.PrintStream err;
//     descriptor: Ljava/io/PrintStream;
//   public static void setIn(java.io.InputStream);
//     descriptor: (Ljava/io/InputStream;)V
//
//   ...
//
// }
func (j *Importer) Import(refs *importers.References) ([]*Class, error) {
	if j.clsMap == nil {
		j.clsMap = make(map[string]*Class)
	}
	clsSet := make(map[string]struct{})
	var names []string
	for _, ref := range refs.Refs {
		// The reference could be to some/pkg.Class or some/pkg/Class.Identifier. Include both.
		pkg := strings.Replace(ref.Pkg, "/", ".", -1)
		for _, cls := range []string{pkg, pkg + "." + ref.Name} {
			if _, exists := clsSet[cls]; !exists {
				clsSet[cls] = struct{}{}
				names = append(names, cls)
			}
		}
	}
	// Make sure toString() is included; it is called when wrapping Java exception types to Go
	// errors.
	refs.Names["ToString"] = struct{}{}
	funcRefs := make(map[funcRef]struct{})
	for _, ref := range refs.Refs {
		pkgName := strings.Replace(ref.Pkg, "/", ".", -1)
		funcRefs[funcRef{pkgName, ref.Name}] = struct{}{}
	}
	classes, err := j.importClasses(names, true)
	if err != nil {
		return nil, err
	}
	j.filterReferences(classes, refs, funcRefs)
	supers, err := j.importReferencedClasses(classes)
	if err != nil {
		return nil, err
	}
	j.filterReferences(supers, refs, funcRefs)
	// Embedders refer to every exported Go struct that will have its class
	// generated. Allow Go code to reverse bind to those classes by synthesizing
	// their class descriptors.
	for _, emb := range refs.Embedders {
		n := emb.Pkg + "." + emb.Name
		if j.JavaPkg != "" {
			n = j.JavaPkg + "." + n
		}
		if _, exists := j.clsMap[n]; exists {
			continue
		}
		clsSet[n] = struct{}{}
		cls := &Class{
			Name:     n,
			FindName: n,
			JNIName:  JNIMangle(n),
			PkgName:  emb.Name,
		}
		for _, ref := range emb.Refs {
			jpkg := strings.Replace(ref.Pkg, "/", ".", -1)
			super := jpkg + "." + ref.Name
			if _, exists := j.clsMap[super]; !exists {
				return nil, fmt.Errorf("failed to find Java class %s, embedded by %s", super, n)
			}
			cls.Supers = append(cls.Supers, super)
		}
		classes = append(classes, cls)
		j.clsMap[cls.Name] = cls
	}
	// Include implicit classes that are used in parameter or return values.
	for _, cls := range classes {
		for _, fsets := range [][]*FuncSet{cls.Funcs, cls.Methods} {
			for _, fs := range fsets {
				for _, f := range fs.Funcs {
					names := j.implicitFuncTypes(f)
					for _, name := range names {
						if _, exists := clsSet[name]; exists {
							continue
						}
						clsSet[name] = struct{}{}
						classes = append(classes, j.clsMap[name])
					}
				}
			}
		}
	}
	for _, cls := range j.clsMap {
		j.fillFuncSigs(cls.Funcs)
		j.fillFuncSigs(cls.Methods)
		for _, m := range cls.Methods {
			j.fillSuperSigs(cls, m)
		}
	}
	for _, cls := range j.clsMap {
		j.fillAllMethods(cls)
	}
	// Include classes that appear as ancestor types for overloaded signatures.
	for _, cls := range classes {
		for _, funcs := range [][]*FuncSet{cls.Funcs, cls.AllMethods} {
			for _, f := range funcs {
				for _, p := range f.Params {
					if p == nil || p.Kind != Object {
						continue
					}
					if _, exists := clsSet[p.Class]; !exists {
						clsSet[p.Class] = struct{}{}
						classes = append(classes, j.clsMap[p.Class])
					}
				}
				if t := f.Ret; t != nil && t.Kind == Object {
					if _, exists := clsSet[t.Class]; !exists {
						clsSet[t.Class] = struct{}{}
						classes = append(classes, j.clsMap[t.Class])
					}
				}
			}
		}
	}
	for _, cls := range classes {
		j.fillJNINames(cls.Funcs)
		j.fillJNINames(cls.AllMethods)
	}
	j.fillThrowables(classes)
	return classes, nil
}

func (j *Importer) fillJNINames(funcs []*FuncSet) {
	for _, fs := range funcs {
		for _, f := range fs.Funcs {
			f.JNIName = JNIMangle(f.Name)
			if len(fs.Funcs) > 1 {
				f.JNIName += "__" + JNIMangle(f.ArgDesc)
			}
		}
	}
}

// commonType finds the most specific type common to t1 and t2.
// If t1 and t2 are both Java classes, the most specific ancestor
// class is returned.
// Else if the types are equal, their type is returned.
// Finally, nil is returned, indicating no common type.
func commonType(clsMap map[string]*Class, t1, t2 *Type) *Type {
	if t1 == nil || t2 == nil {
		return nil
	}
	if reflect.DeepEqual(t1, t2) {
		return t1
	}
	if t1.Kind != Object || t2.Kind != Object {
		// The types are fundamentally incompatible
		return nil
	}
	superSet := make(map[string]struct{})
	supers := []string{t1.Class}
	for len(supers) > 0 {
		var newSupers []string
		for _, s := range supers {
			cls := clsMap[s]
			superSet[s] = struct{}{}
			newSupers = append(newSupers, cls.Supers...)
		}
		supers = newSupers
	}
	supers = []string{t2.Class}
	for len(supers) > 0 {
		var newSupers []string
		for _, s := range supers {
			if _, exists := superSet[s]; exists {
				return &Type{Kind: Object, Class: s}
			}
			cls := clsMap[s]
			newSupers = append(newSupers, cls.Supers...)
		}
		supers = newSupers
	}
	return &Type{Kind: Object, Class: "java.lang.Object"}
}

// combineSigs finds the most specific function signature
// that covers all its overload variants.
// If a function has only one variant, its common signature
// is the signature of that variant.
func combineSigs(clsMap map[string]*Class, sigs ...CommonSig) CommonSig {
	var common CommonSig
	minp := len(sigs[0].Params)
	for i := 1; i < len(sigs); i++ {
		sig := sigs[i]
		n := len(sig.Params)
		common.Variadic = common.Variadic || sig.Variadic || n != minp
		if n < minp {
			minp = n
		}
	}
	for i, sig := range sigs {
		for j, p := range sig.Params {
			idx := j
			// If the common signature is variadic, combine all parameters in the
			// last parameter type of the shortest parameter list.
			if idx > minp {
				idx = minp
			}
			if idx < len(common.Params) {
				common.Params[idx] = commonType(clsMap, common.Params[idx], p)
			} else {
				common.Params = append(common.Params, p)
			}
		}
		common.Throws = common.Throws || sig.Throws
		common.HasRet = common.HasRet || sig.HasRet
		if i > 0 {
			common.Ret = commonType(clsMap, common.Ret, sig.Ret)
		} else {
			common.Ret = sig.Ret
		}
	}
	return common
}

// fillSuperSigs combines methods signatures with super class signatures,
// to preserve the assignability of classes to their super classes.
//
// For example, the class
//
// class A {
//   void f();
// }
//
// is by itself represented by the Go interface
//
// type A interface {
//   f()
// }
//
// However, if class
//
// class B extends A {
//   void f(int);
// }
//
// is also imported, it will be represented as
//
// type B interface {
//   f(...int32)
// }
//
// To make Go B assignable to Go A, the signature of A's f must
// be updated to f(...int32) as well.
func (j *Importer) fillSuperSigs(cls *Class, m *FuncSet) {
	for _, s := range cls.Supers {
		sup := j.clsMap[s]
		if sm, exists := sup.methodMap[m.GoName]; exists {
			sm.CommonSig = combineSigs(j.clsMap, sm.CommonSig, m.CommonSig)
		}
		j.fillSuperSigs(sup, m)
	}
}

func (v *Var) Constant() bool {
	return v.Static && v.Final && v.Val != ""
}

// Mangle a name according to
// http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/design.html#wp16696
//
// TODO: Support unicode characters
func JNIMangle(s string) string {
	var m []byte
	for i := 0; i < len(s); i++ {
		switch c := s[i]; c {
		case '.', '/':
			m = append(m, '_')
		case '$':
			m = append(m, "_00024"...)
		case '_':
			m = append(m, "_1"...)
		case ';':
			m = append(m, "_2"...)
		case '[':
			m = append(m, "_3"...)
		default:
			m = append(m, c)
		}
	}
	return string(m)
}

func (t *Type) Type() string {
	switch t.Kind {
	case Int:
		return "int"
	case Boolean:
		return "boolean"
	case Short:
		return "short"
	case Char:
		return "char"
	case Byte:
		return "byte"
	case Long:
		return "long"
	case Float:
		return "float"
	case Double:
		return "double"
	case String:
		return "String"
	case Array:
		return t.Elem.Type() + "[]"
	case Object:
		return t.Class
	default:
		panic("invalid kind")
	}
}

func (t *Type) JNIType() string {
	switch t.Kind {
	case Int:
		return "jint"
	case Boolean:
		return "jboolean"
	case Short:
		return "jshort"
	case Char:
		return "jchar"
	case Byte:
		return "jbyte"
	case Long:
		return "jlong"
	case Float:
		return "jfloat"
	case Double:
		return "jdouble"
	case String:
		return "jstring"
	case Array:
		return "jarray"
	case Object:
		return "jobject"
	default:
		panic("invalid kind")
	}
}

func (t *Type) CType() string {
	switch t.Kind {
	case Int, Boolean, Short, Char, Byte, Long, Float, Double:
		return t.JNIType()
	case String:
		return "nstring"
	case Array:
		if t.Elem.Kind != Byte {
			panic("unsupported array type")
		}
		return "nbyteslice"
	case Object:
		return "jint"
	default:
		panic("invalid kind")
	}
}

func (t *Type) JNICallType() string {
	switch t.Kind {
	case Int:
		return "Int"
	case Boolean:
		return "Boolean"
	case Short:
		return "Short"
	case Char:
		return "Char"
	case Byte:
		return "Byte"
	case Long:
		return "Long"
	case Float:
		return "Float"
	case Double:
		return "Double"
	case String, Object, Array:
		return "Object"
	default:
		panic("invalid kind")
	}
}

func (j *Importer) filterReferences(classes []*Class, refs *importers.References, funcRefs map[funcRef]struct{}) {
	for _, cls := range classes {
		var filtered []*FuncSet
		for _, f := range cls.Funcs {
			if _, exists := funcRefs[funcRef{cls.Name, f.GoName}]; exists {
				filtered = append(filtered, f)
			}
		}
		cls.Funcs = filtered
		filtered = nil
		for _, m := range cls.Methods {
			if _, exists := refs.Names[m.GoName]; exists {
				filtered = append(filtered, m)
			}
		}
		cls.Methods = filtered
	}
}

// importClasses imports the named classes from the classpaths of the Importer.
func (j *Importer) importClasses(names []string, allowMissingClasses bool) ([]*Class, error) {
	if len(names) == 0 {
		return nil, nil
	}
	args := []string{"-J-Duser.language=en", "-s", "-protected", "-constants"}
	if j.Classpath != "" {
		args = append(args, "-classpath", j.Classpath)
	}
	if j.Bootclasspath != "" {
		args = append(args, "-bootclasspath", j.Bootclasspath)
	}
	args = append(args, names...)
	javapPath, err := javapPath()
	if err != nil {
		return nil, err
	}
	javap := exec.Command(javapPath, args...)
	out, err := javap.CombinedOutput()
	if err != nil {
		if _, ok := err.(*exec.ExitError); !ok {
			return nil, fmt.Errorf("javap failed: %v: %s", err)
		}
		// Not every name is a Java class so an exit error from javap is not
		// fatal.
	}
	s := bufio.NewScanner(bytes.NewBuffer(out))
	var classes []*Class
	for _, name := range names {
		cls, err := j.scanClass(s, name)
		if err != nil {
			_, notfound := err.(*errClsNotFound)
			if notfound && allowMissingClasses {
				continue
			}
			if notfound && name != "android.databinding.DataBindingComponent" {
				return nil, err
			}
			// The Android Databinding library generates android.databinding.DataBindingComponent
			// too late in the build process for the gobind plugin to import it. Synthesize a class
			// for it instead.
			cls = &Class{
				Name:      name,
				FindName:  name,
				Interface: true,
				PkgName:   "databinding",
				JNIName:   JNIMangle(name),
			}
		}
		classes = append(classes, cls)
		j.clsMap[name] = cls
	}
	return classes, nil
}

// importReferencedClasses imports all implicit classes (super types, parameter and
// return types) for the given classes not already imported.
func (j *Importer) importReferencedClasses(classes []*Class) ([]*Class, error) {
	var allCls []*Class
	// Include methods from extended or implemented classes.
	for {
		set := make(map[string]struct{})
		for _, cls := range classes {
			j.unknownImplicitClasses(cls, set)
		}
		if len(set) == 0 {
			break
		}
		var names []string
		for n := range set {
			names = append(names, n)
		}
		newCls, err := j.importClasses(names, false)
		if err != nil {
			return nil, err
		}
		allCls = append(allCls, newCls...)
		classes = newCls
	}
	return allCls, nil
}

func (j *Importer) implicitFuncTypes(f *Func) []string {
	var unk []string
	if rt := f.Ret; rt != nil && rt.Kind == Object {
		unk = append(unk, rt.Class)
	}
	for _, t := range f.Params {
		if t.Kind == Object {
			unk = append(unk, t.Class)
		}
	}
	return unk
}

func (j *Importer) unknownImplicitClasses(cls *Class, set map[string]struct{}) {
	for _, fsets := range [][]*FuncSet{cls.Funcs, cls.Methods} {
		for _, fs := range fsets {
			for _, f := range fs.Funcs {
				names := j.implicitFuncTypes(f)
				for _, name := range names {
					if _, exists := j.clsMap[name]; !exists {
						set[name] = struct{}{}
					}
				}
			}
		}
	}
	for _, n := range cls.Supers {
		if s, exists := j.clsMap[n]; exists {
			j.unknownImplicitClasses(s, set)
		} else {
			set[n] = struct{}{}
		}
	}
}

func (j *Importer) implicitFuncClasses(funcs []*FuncSet, impl []string) []string {
	var l []string
	for _, fs := range funcs {
		for _, f := range fs.Funcs {
			if rt := f.Ret; rt != nil && rt.Kind == Object {
				l = append(l, rt.Class)
			}
			for _, t := range f.Params {
				if t.Kind == Object {
					l = append(l, t.Class)
				}
			}
		}
	}
	return impl
}

func (j *Importer) scanClass(s *bufio.Scanner, name string) (*Class, error) {
	if !s.Scan() {
		return nil, fmt.Errorf("%s: missing javap header", name)
	}
	head := s.Text()
	if errPref := "Error: "; strings.HasPrefix(head, errPref) {
		msg := head[len(errPref):]
		if strings.HasPrefix(msg, "class not found: "+name) {
			return nil, &errClsNotFound{name}
		}
		return nil, errors.New(msg)
	}
	if !strings.HasPrefix(head, "Compiled from ") {
		return nil, fmt.Errorf("%s: unexpected header: %s", name, head)
	}
	if !s.Scan() {
		return nil, fmt.Errorf("%s: missing javap class declaration", name)
	}
	clsDecl := s.Text()
	cls, err := j.scanClassDecl(name, clsDecl)
	if err != nil {
		return nil, err
	}
	cls.JNIName = JNIMangle(cls.Name)
	clsElems := strings.Split(cls.Name, ".")
	cls.PkgName = clsElems[len(clsElems)-1]
	var funcs []*Func
	for s.Scan() {
		decl := strings.TrimSpace(s.Text())
		if decl == "}" {
			break
		} else if decl == "" {
			continue
		}
		if !s.Scan() {
			return nil, fmt.Errorf("%s: missing descriptor for member %q", name, decl)
		}
		desc := strings.TrimSpace(s.Text())
		desc = strings.TrimPrefix(desc, "descriptor: ")
		var static, final, abstract, public bool
		// Trim modifiders from the declaration.
	loop:
		for {
			idx := strings.Index(decl, " ")
			if idx == -1 {
				break
			}
			keyword := decl[:idx]
			switch keyword {
			case "public":
				public = true
			case "protected", "native":
				// ignore
			case "static":
				static = true
			case "final":
				final = true
			case "abstract":
				abstract = true
			default:
				// Hopefully we reached the declaration now.
				break loop
			}
			decl = decl[idx+1:]
		}
		// Trim ending ;
		decl = decl[:len(decl)-1]
		if idx := strings.Index(decl, "("); idx != -1 {
			f, err := j.scanMethod(decl, desc, idx)
			if err != nil {
				return nil, fmt.Errorf("%s: %v", name, err)
			}
			if f != nil {
				f.Static = static
				f.Abstract = abstract
				f.Public = public || cls.Interface
				f.Final = final
				f.Constructor = f.Name == cls.FindName
				if f.Constructor {
					cls.HasNoArgCon = cls.HasNoArgCon || len(f.Params) == 0
					f.Public = f.Public && !cls.Abstract
					f.Name = "new"
					f.Ret = &Type{Class: name, Kind: Object}
				}
				funcs = append(funcs, f)
			}
		} else {
			// Member is a variable
			v, err := j.scanVar(decl, desc)
			if err != nil {
				return nil, fmt.Errorf("%s: %v", name, err)
			}
			if v != nil && public {
				v.Static = static
				v.Final = final
				cls.Vars = append(cls.Vars, v)
			}
		}
	}
	for _, f := range funcs {
		var m map[string]*FuncSet
		var l *[]*FuncSet
		goName := initialUpper(f.Name)
		if f.Static || f.Constructor {
			m = cls.funcMap
			l = &cls.Funcs
		} else {
			m = cls.methodMap
			l = &cls.Methods
		}
		fs, exists := m[goName]
		if !exists {
			fs = &FuncSet{
				Name:   f.Name,
				GoName: goName,
			}
			m[goName] = fs
			*l = append(*l, fs)
		}
		fs.Funcs = append(fs.Funcs, f)
	}
	return cls, nil
}

func (j *Importer) scanClassDecl(name string, decl string) (*Class, error) {
	isRoot := name == "java.lang.Object"
	cls := &Class{
		Name:        name,
		funcMap:     make(map[string]*FuncSet),
		methodMap:   make(map[string]*FuncSet),
		HasNoArgCon: isRoot,
	}
	const (
		stMod = iota
		stName
		stExt
		stImpl
	)
	superClsDecl := isRoot
	st := stMod
	var w []byte
	// if > 0, we're inside a generics declaration
	gennest := 0
	for i := 0; i < len(decl); i++ {
		c := decl[i]
		switch c {
		default:
			if gennest == 0 {
				w = append(w, c)
			}
		case '>':
			gennest--
		case '<':
			gennest++
		case '{':
			if !superClsDecl && !cls.Interface {
				cls.Supers = append(cls.Supers, "java.lang.Object")
			}
			return cls, nil
		case ' ', ',':
			if gennest > 0 {
				break
			}
			switch w := string(w); w {
			default:
				switch st {
				case stName:
					if strings.Replace(w, "$", ".", -1) != strings.Replace(name, "$", ".", -1) {
						return nil, fmt.Errorf("unexpected name %q in class declaration: %q", w, decl)
					}
					cls.FindName = w
				case stExt:
					superClsDecl = true
					cls.Supers = append(cls.Supers, w)
				case stImpl:
					if !cls.Interface {
						cls.Supers = append(cls.Supers, w)
					}
				default:
					return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
				}
			case "":
				// skip
			case "public":
				if st != stMod {
					return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
				}
			case "abstract":
				if st != stMod {
					return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
				}
				cls.Abstract = true
			case "final":
				if st != stMod {
					return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
				}
				cls.Final = true
			case "interface":
				cls.Interface = true
				fallthrough
			case "class":
				if st != stMod {
					return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
				}
				st = stName
			case "extends":
				if st != stName {
					return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
				}
				st = stExt
			case "implements":
				if st != stName && st != stExt {
					return nil, fmt.Errorf("unexpected %q in class declaration: %q", w, decl)
				}
				st = stImpl
			}
			w = w[:0]
		}
	}
	return nil, fmt.Errorf("missing ending { in class declaration: %q", decl)
}

func (j *Importer) scanVar(decl, desc string) (*Var, error) {
	v := new(Var)
	const eq = " = "
	idx := strings.Index(decl, eq)
	if idx != -1 {
		val, ok := j.parseJavaValue(decl[idx+len(eq):])
		if !ok {
			// Skip constants that cannot be represented in Go
			return nil, nil
		}
		v.Val = val
	} else {
		idx = len(decl)
	}
	for i := idx - 1; i >= 0; i-- {
		if i == 0 || decl[i-1] == ' ' {
			v.Name = decl[i:idx]
			break
		}
	}
	if v.Name == "" {
		return nil, fmt.Errorf("unable to parse member name from declaration: %q", decl)
	}
	typ, _, err := j.parseJavaType(desc)
	if err != nil {
		return nil, fmt.Errorf("invalid type signature for %s: %q", v.Name, desc)
	}
	v.Type = typ
	return v, nil
}

func (j *Importer) scanMethod(decl, desc string, parenIdx int) (*Func, error) {
	// Member is a method
	f := new(Func)
	f.Desc = desc
	for i := parenIdx - 1; i >= 0; i-- {
		if i == 0 || decl[i-1] == ' ' {
			f.Name = decl[i:parenIdx]
			break
		}
	}
	if f.Name == "" {
		return nil, fmt.Errorf("unable to parse method name from declaration: %q", decl)
	}
	if desc[0] != '(' {
		return nil, fmt.Errorf("invalid descriptor for method %s: %q", f.Name, desc)
	}
	const throws = " throws "
	if idx := strings.Index(decl, throws); idx != -1 {
		f.Throws = decl[idx+len(throws):]
	}
	i := 1
	for desc[i] != ')' {
		typ, n, err := j.parseJavaType(desc[i:])
		if err != nil {
			return nil, fmt.Errorf("invalid descriptor for method %s: %v", f.Name, err)
		}
		i += n
		f.Params = append(f.Params, typ)
	}
	f.ArgDesc = desc[1:i]
	i++ // skip ending )
	if desc[i] != 'V' {
		typ, _, err := j.parseJavaType(desc[i:])
		if err != nil {
			return nil, fmt.Errorf("invalid descriptor for method %s: %v", f.Name, err)
		}
		f.Ret = typ
	}
	return f, nil
}

func (j *Importer) fillThrowables(classes []*Class) {
	thrCls, ok := j.clsMap["java.lang.Throwable"]
	if !ok {
		// If Throwable isn't in the class map
		// no imported class inherits from Throwable
		return
	}
	for _, cls := range classes {
		j.fillThrowableFor(cls, thrCls)
	}
}

func (j *Importer) fillThrowableFor(cls, thrCls *Class) {
	if cls.Interface || cls.Throwable {
		return
	}
	cls.Throwable = cls == thrCls
	for _, name := range cls.Supers {
		sup := j.clsMap[name]
		j.fillThrowableFor(sup, thrCls)
		cls.Throwable = cls.Throwable || sup.Throwable
	}
}

func commonSig(f *Func) CommonSig {
	return CommonSig{
		Params: f.Params,
		Ret:    f.Ret,
		HasRet: f.Ret != nil,
		Throws: f.Throws != "",
	}
}

func (j *Importer) fillFuncSigs(funcs []*FuncSet) {
	for _, fs := range funcs {
		var sigs []CommonSig
		for _, f := range fs.Funcs {
			sigs = append(sigs, commonSig(f))
		}
		fs.CommonSig = combineSigs(j.clsMap, sigs...)
	}
}

func (j *Importer) fillAllMethods(cls *Class) {
	if len(cls.AllMethods) > 0 {
		return
	}
	for _, supName := range cls.Supers {
		super := j.clsMap[supName]
		j.fillAllMethods(super)
	}
	var fsets []*FuncSet
	fsets = append(fsets, cls.Methods...)
	for _, supName := range cls.Supers {
		super := j.clsMap[supName]
		fsets = append(fsets, super.AllMethods...)
	}
	sigs := make(map[FuncSig]struct{})
	methods := make(map[string]*FuncSet)
	for _, fs := range fsets {
		clsFs, exists := methods[fs.Name]
		if !exists {
			clsFs = &FuncSet{
				Name:      fs.Name,
				GoName:    fs.GoName,
				CommonSig: fs.CommonSig,
			}
			cls.AllMethods = append(cls.AllMethods, clsFs)
			methods[fs.Name] = clsFs
		} else {
			// Combine the (overloaded) signature with the other variants.
			clsFs.CommonSig = combineSigs(j.clsMap, clsFs.CommonSig, fs.CommonSig)
		}
		for _, f := range fs.Funcs {
			if _, exists := sigs[f.FuncSig]; exists {
				continue
			}
			sigs[f.FuncSig] = struct{}{}
			clsFs.Funcs = append(clsFs.Funcs, f)
		}
	}
}

func (j *Importer) parseJavaValue(v string) (string, bool) {
	v = strings.TrimRight(v, "ldf")
	switch v {
	case "", "NaN", "Infinity", "-Infinity":
		return "", false
	default:
		if v[0] == '\'' {
			// Skip character constants, since they can contain invalid code points
			// that are unacceptable to Go.
			return "", false
		}
		return v, true
	}
}

func (j *Importer) parseJavaType(desc string) (*Type, int, error) {
	t := new(Type)
	var n int
	if desc == "" {
		return t, n, errors.New("empty type signature")
	}
	n++
	switch desc[0] {
	case 'Z':
		t.Kind = Boolean
	case 'B':
		t.Kind = Byte
	case 'C':
		t.Kind = Char
	case 'S':
		t.Kind = Short
	case 'I':
		t.Kind = Int
	case 'J':
		t.Kind = Long
	case 'F':
		t.Kind = Float
	case 'D':
		t.Kind = Double
	case 'L':
		var clsName string
		for i := n; i < len(desc); i++ {
			if desc[i] == ';' {
				clsName = strings.Replace(desc[n:i], "/", ".", -1)
				clsName = strings.Replace(clsName, "$", ".", -1)
				n += i - n + 1
				break
			}
		}
		if clsName == "" {
			return t, n, errors.New("missing ; in class type signature")
		}
		if clsName == "java.lang.String" {
			t.Kind = String
		} else {
			t.Kind = Object
			t.Class = clsName
		}
	case '[':
		et, n2, err := j.parseJavaType(desc[n:])
		if err != nil {
			return t, n, err
		}
		n += n2
		t.Kind = Array
		t.Elem = et
	default:
		return t, n, fmt.Errorf("invalid type signature: %s", desc)
	}
	return t, n, nil
}

func initialUpper(s string) string {
	if s == "" {
		return ""
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToUpper(r)) + s[n:]
}
