// 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 reports 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,
			HasNoArgCon: true,
		}
		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"}
	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", 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:]
}
