// Copyright 2014 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.

package bind

import (
	"fmt"
	"go/constant"
	"go/types"
	"html"
	"math"
	"reflect"
	"regexp"
	"strings"

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

// TODO(crawshaw): disallow basic android java type names in exported symbols.
// TODO(crawshaw): consider introducing Java functions for casting to and from interfaces at runtime.

type JavaGen struct {
	// JavaPkg is the Java package prefix for the generated classes. The prefix is prepended to the Go
	// package name to create the full Java package name.
	JavaPkg string

	*Generator

	jstructs map[*types.TypeName]*javaClassInfo
	clsMap   map[string]*java.Class
	// Constructors is a map from Go struct types to a list
	// of exported constructor functions for the type, on the form
	// func New<Type>(...) *Type
	constructors map[*types.TypeName][]*types.Func
}

type javaClassInfo struct {
	// The Java class this class extends.
	extends *java.Class
	// All Java classes and interfaces this class extends and implements.
	supers  []*java.Class
	methods map[string]*java.FuncSet
	// Does the class need a default no-arg constructor
	genNoargCon bool
}

// Init intializes the embedded Generator and initializes the Java class information
// needed to generate structs that extend Java classes and interfaces.
func (g *JavaGen) Init(classes []*java.Class) {
	g.Generator.Init()
	g.clsMap = make(map[string]*java.Class)
	for _, cls := range classes {
		g.clsMap[cls.Name] = cls
	}
	g.jstructs = make(map[*types.TypeName]*javaClassInfo)
	g.constructors = make(map[*types.TypeName][]*types.Func)
	for _, s := range g.structs {
		classes := embeddedJavaClasses(s.t)
		if len(classes) == 0 {
			continue
		}
		inf := &javaClassInfo{
			methods:     make(map[string]*java.FuncSet),
			genNoargCon: true, // java.lang.Object has a no-arg constructor
		}
		for _, n := range classes {
			cls := g.clsMap[n]
			for _, fs := range cls.AllMethods {
				hasMeth := false
				for _, f := range fs.Funcs {
					if !f.Final {
						hasMeth = true
					}
				}
				if hasMeth {
					inf.methods[fs.GoName] = fs
				}
			}
			inf.supers = append(inf.supers, cls)
			if !cls.Interface {
				if inf.extends != nil {
					g.errorf("%s embeds more than one Java class; only one is allowed.", s.obj)
				}
				if cls.Final {
					g.errorf("%s embeds final Java class %s", s.obj, cls.Name)
				}
				inf.extends = cls
				inf.genNoargCon = cls.HasNoArgCon
			}
		}
		g.jstructs[s.obj] = inf
	}
	for _, f := range g.funcs {
		if t := g.constructorType(f); t != nil {
			jinf := g.jstructs[t]
			if jinf != nil {
				sig := f.Type().(*types.Signature)
				jinf.genNoargCon = jinf.genNoargCon && sig.Params().Len() > 0
			}
			g.constructors[t] = append(g.constructors[t], f)
		}
	}
}

func (j *javaClassInfo) toJavaType(T types.Type) *java.Type {
	switch T := T.(type) {
	case *types.Basic:
		var kind java.TypeKind
		switch T.Kind() {
		case types.Bool, types.UntypedBool:
			kind = java.Boolean
		case types.Uint8:
			kind = java.Byte
		case types.Int16:
			kind = java.Short
		case types.Int32, types.UntypedRune: // types.Rune
			kind = java.Int
		case types.Int64, types.UntypedInt:
			kind = java.Long
		case types.Float32:
			kind = java.Float
		case types.Float64, types.UntypedFloat:
			kind = java.Double
		case types.String, types.UntypedString:
			kind = java.String
		default:
			return nil
		}
		return &java.Type{Kind: kind}
	case *types.Slice:
		switch e := T.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				return &java.Type{Kind: java.Array, Elem: &java.Type{Kind: java.Byte}}
			}
		}
		return nil
	case *types.Named:
		if isJavaType(T) {
			return &java.Type{Kind: java.Object, Class: classNameFor(T)}
		}
	}
	return nil
}

// lookupMethod searches the Java class descriptor for a method
// that matches the Go method.
func (j *javaClassInfo) lookupMethod(m *types.Func, hasThis bool) *java.Func {
	jm := j.methods[m.Name()]
	if jm == nil {
		// If an exact match is not found, try the method with trailing underscores
		// stripped. This way, name clashes can be avoided when overriding multiple
		// overloaded methods from Go.
		base := strings.TrimRight(m.Name(), "_")
		jm = j.methods[base]
		if jm == nil {
			return nil
		}
	}
	// A name match was found. Now use the parameter and return types to locate
	// the correct variant.
	sig := m.Type().(*types.Signature)
	params := sig.Params()
	// Convert Go parameter types to their Java counterparts, if possible.
	var jparams []*java.Type
	i := 0
	if hasThis {
		i = 1
	}
	for ; i < params.Len(); i++ {
		jparams = append(jparams, j.toJavaType(params.At(i).Type()))
	}
	var ret *java.Type
	var throws bool
	if results := sig.Results(); results.Len() > 0 {
		ret = j.toJavaType(results.At(0).Type())
		if results.Len() > 1 {
			throws = isErrorType(results.At(1).Type())
		}
	}
loop:
	for _, f := range jm.Funcs {
		if len(f.Params) != len(jparams) {
			continue
		}
		if throws != (f.Throws != "") {
			continue
		}
		if !reflect.DeepEqual(ret, f.Ret) {
			continue
		}
		for i, p := range f.Params {
			if !reflect.DeepEqual(p, jparams[i]) {
				continue loop
			}
		}
		return f
	}
	return nil
}

// ClassNames returns the list of names of the generated Java classes and interfaces.
func (g *JavaGen) ClassNames() []string {
	var names []string
	for _, s := range g.structs {
		names = append(names, g.javaTypeName(s.obj.Name()))
	}
	for _, iface := range g.interfaces {
		names = append(names, g.javaTypeName(iface.obj.Name()))
	}
	return names
}

func (g *JavaGen) GenClass(idx int) error {
	ns := len(g.structs)
	if idx < ns {
		s := g.structs[idx]
		g.genStruct(s)
	} else {
		iface := g.interfaces[idx-ns]
		g.genInterface(iface)
	}
	if len(g.err) > 0 {
		return g.err
	}
	return nil
}

func (g *JavaGen) genProxyImpl(name string) {
	g.Printf("private final Seq.Ref ref;\n\n")
	g.Printf("@Override public final int incRefnum() {\n")
	g.Printf("      int refnum = ref.refnum;\n")
	g.Printf("      Seq.incGoRef(refnum);\n")
	g.Printf("      return refnum;\n")
	g.Printf("}\n\n")
}

func (g *JavaGen) genStruct(s structInfo) {
	pkgPath := ""
	if g.Pkg != nil {
		pkgPath = g.Pkg.Path()
	}
	n := g.javaTypeName(s.obj.Name())
	g.Printf(javaPreamble, g.javaPkgName(g.Pkg), n, g.gobindOpts(), pkgPath)

	fields := exportedFields(s.t)
	methods := exportedMethodSet(types.NewPointer(s.obj.Type()))

	var impls []string
	jinf := g.jstructs[s.obj]
	if jinf != nil {
		impls = append(impls, "Seq.GoObject")
		for _, cls := range jinf.supers {
			if cls.Interface {
				impls = append(impls, g.javaTypeName(cls.Name))
			}
		}
	} else {
		impls = append(impls, "Seq.Proxy")
	}

	pT := types.NewPointer(s.obj.Type())
	for _, iface := range g.allIntf {
		if types.AssignableTo(pT, iface.obj.Type()) {
			n := iface.obj.Name()
			if p := iface.obj.Pkg(); p != g.Pkg {
				if n == JavaClassName(p) {
					n = n + "_"
				}
				n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n)
			} else {
				n = g.javaTypeName(n)
			}
			impls = append(impls, n)
		}
	}

	doc := g.docs[n]
	g.javadoc(doc.Doc())
	g.Printf("public final class %s", n)
	if jinf != nil {
		if jinf.extends != nil {
			g.Printf(" extends %s", g.javaTypeName(jinf.extends.Name))
		}
	}
	if len(impls) > 0 {
		g.Printf(" implements %s", strings.Join(impls, ", "))
	}
	g.Printf(" {\n")
	g.Indent()

	g.Printf("static { %s.touch(); }\n\n", g.className())
	g.genProxyImpl(n)
	cons := g.constructors[s.obj]
	for _, f := range cons {
		if !g.isSigSupported(f.Type()) {
			g.Printf("// skipped constructor %s.%s with unsupported parameter or return types\n\n", n, f.Name())
			continue
		}
		g.genConstructor(f, n, jinf != nil)
	}
	if jinf == nil || jinf.genNoargCon {
		// constructor for Go instantiated instances.
		g.Printf("%s(Seq.Ref ref) { this.ref = ref; }\n\n", n)
		if len(cons) == 0 {
			// Generate default no-arg constructor
			g.Printf("public %s() { this.ref = __New(); }\n\n", n)
			g.Printf("private static native Seq.Ref __New();\n\n")
		}
	}

	for _, f := range fields {
		if t := f.Type(); !g.isSupported(t) {
			g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", n, f.Name(), t)
			continue
		}

		fdoc := doc.Member(f.Name())
		g.javadoc(fdoc)
		g.Printf("public final native %s get%s();\n", g.javaType(f.Type()), f.Name())
		g.javadoc(fdoc)
		g.Printf("public final native void set%s(%s v);\n\n", f.Name(), g.javaType(f.Type()))
	}

	var isStringer bool
	for _, m := range methods {
		if !g.isSigSupported(m.Type()) {
			g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", n, m.Name())
			continue
		}
		g.javadoc(doc.Member(m.Name()))
		var jm *java.Func
		hasThis := false
		if jinf != nil {
			hasThis = g.hasThis(n, m)
			jm = jinf.lookupMethod(m, hasThis)
			if jm != nil {
				g.Printf("@Override ")
			}
		}
		g.Printf("public native ")
		g.genFuncSignature(m, jm, hasThis)
		t := m.Type().(*types.Signature)
		isStringer = isStringer || (m.Name() == "String" && t.Params().Len() == 0 && t.Results().Len() == 1 &&
			types.Identical(t.Results().At(0).Type(), types.Typ[types.String]))
	}

	if jinf == nil {
		g.genObjectMethods(n, fields, isStringer)
	}

	g.Outdent()
	g.Printf("}\n\n")
}

// javaTypeName returns the class name of a given Go type name. If
// the type name clashes with the package class name, an underscore is
// appended.
func (g *JavaGen) javaTypeName(n string) string {
	if n == JavaClassName(g.Pkg) {
		return n + "_"
	}
	return n
}

func (g *JavaGen) javadoc(doc string) {
	if doc == "" {
		return
	}
	// JavaDoc expects HTML-escaped documentation.
	g.Printf("/**\n * %s */\n", html.EscapeString(doc))
}

// hasThis returns whether a method has an implicit "this" parameter.
func (g *JavaGen) hasThis(sName string, m *types.Func) bool {
	sig := m.Type().(*types.Signature)
	params := sig.Params()
	if params.Len() == 0 {
		return false
	}
	v := params.At(0)
	if v.Name() != "this" {
		return false
	}
	t, ok := v.Type().(*types.Named)
	if !ok {
		return false
	}
	obj := t.Obj()
	pkg := obj.Pkg()
	if pkgFirstElem(pkg) != "Java" {
		return false
	}
	clsName := classNameFor(t)
	exp := g.javaPkgName(g.Pkg) + "." + sName
	if clsName != exp {
		g.errorf("the type %s of the `this` argument to method %s.%s is not %s", clsName, sName, m.Name(), exp)
		return false
	}
	return true
}

func (g *JavaGen) genConstructor(f *types.Func, n string, jcls bool) {
	g.javadoc(g.docs[f.Name()].Doc())
	g.Printf("public %s(", n)
	g.genFuncArgs(f, nil, false)
	g.Printf(") {\n")
	g.Indent()
	sig := f.Type().(*types.Signature)
	params := sig.Params()
	if jcls {
		g.Printf("super(")
		for i := 0; i < params.Len(); i++ {
			if i > 0 {
				g.Printf(", ")
			}
			g.Printf(g.paramName(params, i))
		}
		g.Printf(");\n")
	}
	g.Printf("this.ref = ")
	g.Printf("__%s(", f.Name())
	for i := 0; i < params.Len(); i++ {
		if i > 0 {
			g.Printf(", ")
		}
		g.Printf(g.paramName(params, i))
	}
	g.Printf(");\n")
	g.Outdent()
	g.Printf("}\n\n")
	g.Printf("private static native Seq.Ref __%s(", f.Name())
	g.genFuncArgs(f, nil, false)
	g.Printf(");\n\n")
}

// genFuncArgs generated Java function arguments declaration for the function f.
// If the supplied overridden java function is supplied, genFuncArgs omits the implicit
// this argument.
func (g *JavaGen) genFuncArgs(f *types.Func, jm *java.Func, hasThis bool) {
	sig := f.Type().(*types.Signature)
	params := sig.Params()
	first := 0
	if hasThis {
		// Skip the implicit this argument to the Go method
		first = 1
	}
	for i := first; i < params.Len(); i++ {
		if i > first {
			g.Printf(", ")
		}
		v := params.At(i)
		name := g.paramName(params, i)
		jt := g.javaType(v.Type())
		g.Printf("%s %s", jt, name)
	}
}

func (g *JavaGen) genObjectMethods(n string, fields []*types.Var, isStringer bool) {
	g.Printf("@Override public boolean equals(Object o) {\n")
	g.Indent()
	g.Printf("if (o == null || !(o instanceof %s)) {\n    return false;\n}\n", n)
	g.Printf("%s that = (%s)o;\n", n, n)
	for _, f := range fields {
		if t := f.Type(); !g.isSupported(t) {
			g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", n, f.Name(), t)
			continue
		}
		nf := f.Name()
		g.Printf("%s this%s = get%s();\n", g.javaType(f.Type()), nf, nf)
		g.Printf("%s that%s = that.get%s();\n", g.javaType(f.Type()), nf, nf)
		if isJavaPrimitive(f.Type()) {
			g.Printf("if (this%s != that%s) {\n    return false;\n}\n", nf, nf)
		} else {
			g.Printf("if (this%s == null) {\n", nf)
			g.Indent()
			g.Printf("if (that%s != null) {\n    return false;\n}\n", nf)
			g.Outdent()
			g.Printf("} else if (!this%s.equals(that%s)) {\n    return false;\n}\n", nf, nf)
		}
	}
	g.Printf("return true;\n")
	g.Outdent()
	g.Printf("}\n\n")

	g.Printf("@Override public int hashCode() {\n")
	g.Printf("    return java.util.Arrays.hashCode(new Object[] {")
	idx := 0
	for _, f := range fields {
		if t := f.Type(); !g.isSupported(t) {
			continue
		}
		if idx > 0 {
			g.Printf(", ")
		}
		idx++
		g.Printf("get%s()", f.Name())
	}
	g.Printf("});\n")
	g.Printf("}\n\n")

	g.Printf("@Override public String toString() {\n")
	g.Indent()
	if isStringer {
		g.Printf("return string();\n")
	} else {
		g.Printf("StringBuilder b = new StringBuilder();\n")
		g.Printf(`b.append("%s").append("{");`, n)
		g.Printf("\n")
		for _, f := range fields {
			if t := f.Type(); !g.isSupported(t) {
				continue
			}
			n := f.Name()
			g.Printf(`b.append("%s:").append(get%s()).append(",");`, n, n)
			g.Printf("\n")
		}
		g.Printf(`return b.append("}").toString();`)
		g.Printf("\n")
	}
	g.Outdent()
	g.Printf("}\n")
}

func (g *JavaGen) genInterface(iface interfaceInfo) {
	pkgPath := ""
	if g.Pkg != nil {
		pkgPath = g.Pkg.Path()
	}
	g.Printf(javaPreamble, g.javaPkgName(g.Pkg), g.javaTypeName(iface.obj.Name()), g.gobindOpts(), pkgPath)

	var exts []string
	numM := iface.t.NumMethods()
	for _, other := range g.allIntf {
		// Only extend interfaces with fewer methods to avoid circular references
		if other.t.NumMethods() < numM && types.AssignableTo(iface.t, other.t) {
			n := other.obj.Name()
			if p := other.obj.Pkg(); p != g.Pkg {
				if n == JavaClassName(p) {
					n = n + "_"
				}
				n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n)
			} else {
				n = g.javaTypeName(n)
			}
			exts = append(exts, n)
		}
	}
	doc := g.docs[iface.obj.Name()]
	g.javadoc(doc.Doc())
	g.Printf("public interface %s", g.javaTypeName(iface.obj.Name()))
	if len(exts) > 0 {
		g.Printf(" extends %s", strings.Join(exts, ", "))
	}
	g.Printf(" {\n")
	g.Indent()

	for _, m := range iface.summary.callable {
		if !g.isSigSupported(m.Type()) {
			g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
			continue
		}
		g.javadoc(doc.Member(m.Name()))
		g.Printf("public ")
		g.genFuncSignature(m, nil, false)
	}

	g.Printf("\n")

	g.Outdent()
	g.Printf("}\n\n")
}

func isJavaPrimitive(T types.Type) bool {
	b, ok := T.(*types.Basic)
	if !ok {
		return false
	}
	switch b.Kind() {
	case types.Bool, types.Uint8, types.Float32, types.Float64,
		types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
		return true
	}
	return false
}

// jniType returns a string that can be used as a JNI type.
func (g *JavaGen) jniType(T types.Type) string {
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool, types.UntypedBool:
			return "jboolean"
		case types.Int:
			return "jlong"
		case types.Int8:
			return "jbyte"
		case types.Int16:
			return "jshort"
		case types.Int32, types.UntypedRune: // types.Rune
			return "jint"
		case types.Int64, types.UntypedInt:
			return "jlong"
		case types.Uint8: // types.Byte
			// TODO(crawshaw): Java bytes are signed, so this is
			// questionable, but vital.
			return "jbyte"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "jfloat"
		case types.Float64, types.UntypedFloat:
			return "jdouble"
		case types.String, types.UntypedString:
			return "jstring"
		default:
			g.errorf("unsupported basic type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		return "jbyteArray"

	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.jniType(T.Elem())
		}
		g.errorf("unsupported pointer to type: %s", T)
	case *types.Named:
		return "jobject"
	default:
		g.errorf("unsupported jniType: %#+v, %s\n", T, T)
	}
	return "TODO"
}

func (g *JavaGen) javaBasicType(T *types.Basic) string {
	switch T.Kind() {
	case types.Bool, types.UntypedBool:
		return "boolean"
	case types.Int:
		return "long"
	case types.Int8:
		return "byte"
	case types.Int16:
		return "short"
	case types.Int32, types.UntypedRune: // types.Rune
		return "int"
	case types.Int64, types.UntypedInt:
		return "long"
	case types.Uint8: // types.Byte
		// TODO(crawshaw): Java bytes are signed, so this is
		// questionable, but vital.
		return "byte"
	// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
	case types.Float32:
		return "float"
	case types.Float64, types.UntypedFloat:
		return "double"
	case types.String, types.UntypedString:
		return "String"
	default:
		g.errorf("unsupported basic type: %s", T)
		return "TODO"
	}
}

// javaType returns a string that can be used as a Java type.
func (g *JavaGen) javaType(T types.Type) string {
	if isErrorType(T) {
		// The error type is usually translated into an exception in
		// Java, however the type can be exposed in other ways, such
		// as an exported field.
		return "java.lang.Exception"
	} else if isJavaType(T) {
		return classNameFor(T)
	}
	switch T := T.(type) {
	case *types.Basic:
		return g.javaBasicType(T)
	case *types.Slice:
		elem := g.javaType(T.Elem())
		return elem + "[]"

	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.javaType(T.Elem())
		}
		g.errorf("unsupported pointer to type: %s", T)
	case *types.Named:
		n := T.Obj()
		nPkg := n.Pkg()
		if !isErrorType(T) && !g.validPkg(nPkg) {
			g.errorf("type %s is in %s, which is not bound", n.Name(), nPkg)
			break
		}
		// TODO(crawshaw): more checking here
		clsName := n.Name()
		if nPkg != g.Pkg {
			if clsName == JavaClassName(nPkg) {
				clsName += "_"
			}
			return fmt.Sprintf("%s.%s", g.javaPkgName(nPkg), clsName)
		} else {
			return g.javaTypeName(clsName)
		}
	default:
		g.errorf("unsupported javaType: %#+v, %s\n", T, T)
	}
	return "TODO"
}

func (g *JavaGen) genJNIFuncSignature(o *types.Func, sName string, jm *java.Func, proxy, isjava bool) {
	sig := o.Type().(*types.Signature)
	res := sig.Results()

	var ret string
	switch res.Len() {
	case 2:
		ret = g.jniType(res.At(0).Type())
	case 1:
		if isErrorType(res.At(0).Type()) {
			ret = "void"
		} else {
			ret = g.jniType(res.At(0).Type())
		}
	case 0:
		ret = "void"
	default:
		g.errorf("too many result values: %s", o)
		return
	}

	g.Printf("JNIEXPORT %s JNICALL\n", ret)
	g.Printf("Java_%s_", g.jniPkgName())
	if sName != "" {
		if proxy {
			g.Printf(g.className())
			// 0024 is the mangled form of $, for naming inner classes.
			g.Printf("_00024proxy%s", sName)
		} else {
			g.Printf(java.JNIMangle(g.javaTypeName(sName)))
		}
	} else {
		g.Printf(g.className())
	}
	g.Printf("_")
	if jm != nil {
		g.Printf(jm.JNIName)
	} else {
		oName := javaNameReplacer(lowerFirst(o.Name()))
		g.Printf(java.JNIMangle(oName))
	}
	g.Printf("(JNIEnv* env, ")
	if sName != "" {
		g.Printf("jobject __this__")
	} else {
		g.Printf("jclass _clazz")
	}
	params := sig.Params()
	i := 0
	if isjava && params.Len() > 0 && params.At(0).Name() == "this" {
		// Skip the implicit this argument, if any.
		i = 1
	}
	for ; i < params.Len(); i++ {
		g.Printf(", ")
		v := sig.Params().At(i)
		name := g.paramName(params, i)
		jt := g.jniType(v.Type())
		g.Printf("%s %s", jt, name)
	}
	g.Printf(")")
}

func (g *JavaGen) jniPkgName() string {
	return strings.Replace(java.JNIMangle(g.javaPkgName(g.Pkg)), ".", "_", -1)
}

var javaLetterDigitRE = regexp.MustCompile(`[0-9a-zA-Z$_]`)

func (g *JavaGen) paramName(params *types.Tuple, pos int) string {
	name := basicParamName(params, pos)
	if !javaLetterDigitRE.MatchString(name) {
		name = fmt.Sprintf("p%d", pos)
	}
	return javaNameReplacer(name)
}

func (g *JavaGen) genFuncSignature(o *types.Func, jm *java.Func, hasThis bool) {
	sig := o.Type().(*types.Signature)
	res := sig.Results()

	var returnsError bool
	var ret string
	switch res.Len() {
	case 2:
		if !isErrorType(res.At(1).Type()) {
			g.errorf("second result value must be of type error: %s", o)
			return
		}
		returnsError = true
		ret = g.javaType(res.At(0).Type())
	case 1:
		if isErrorType(res.At(0).Type()) {
			returnsError = true
			ret = "void"
		} else {
			ret = g.javaType(res.At(0).Type())
		}
	case 0:
		ret = "void"
	default:
		g.errorf("too many result values: %s", o)
		return
	}

	g.Printf("%s ", ret)
	if jm != nil {
		g.Printf(jm.Name)
	} else {
		g.Printf(javaNameReplacer(lowerFirst(o.Name())))
	}
	g.Printf("(")
	g.genFuncArgs(o, jm, hasThis)
	g.Printf(")")
	if returnsError {
		if jm != nil {
			if jm.Throws == "" {
				g.errorf("%s declares an error return value but the overriden method does not throw", o)
				return
			}
			g.Printf(" throws %s", jm.Throws)
		} else {
			g.Printf(" throws Exception")
		}
	}
	g.Printf(";\n")
}

func (g *JavaGen) genVar(o *types.Var) {
	if t := o.Type(); !g.isSupported(t) {
		g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t)
		return
	}
	jType := g.javaType(o.Type())

	doc := g.docs[o.Name()].Doc()
	// setter
	g.javadoc(doc)
	g.Printf("public static native void set%s(%s v);\n", o.Name(), jType)

	// getter
	g.javadoc(doc)
	g.Printf("public static native %s get%s();\n\n", jType, o.Name())
}

// genCRetClear clears the result value from a JNI call if an exception was
// raised.
func (g *JavaGen) genCRetClear(varName string, t types.Type, exc string) {
	g.Printf("if (%s != NULL) {\n", exc)
	g.Indent()
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("%s = NULL;\n", varName)
		default:
			g.Printf("%s = 0;\n", varName)
		}
	case *types.Slice, *types.Named, *types.Pointer:
		g.Printf("%s = NULL;\n", varName)
	}
	g.Outdent()
	g.Printf("}\n")
}

func (g *JavaGen) genJavaToC(varName string, t types.Type, mode varMode) {
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("nstring _%s = go_seq_from_java_string(env, %s);\n", varName, varName)
		default:
			g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("nbyteslice _%s = go_seq_from_java_bytearray(env, %s, %d);\n", varName, varName, toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Named:
		switch u := t.Underlying().(type) {
		case *types.Interface:
			g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName)
		default:
			g.errorf("unsupported named type: %s / %T", u, u)
		}
	case *types.Pointer:
		g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName)
	default:
		g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
	}
}

func (g *JavaGen) genCToJava(toName, fromName string, t types.Type, mode varMode) {
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("jstring %s = go_seq_to_java_string(env, %s);\n", toName, fromName)
		case types.Bool:
			g.Printf("jboolean %s = %s ? JNI_TRUE : JNI_FALSE;\n", toName, fromName)
		default:
			g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("jbyteArray %s = go_seq_to_java_bytearray(env, %s, %d);\n", toName, fromName, toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Pointer:
		// TODO(crawshaw): test *int
		// TODO(crawshaw): test **Generator
		switch t := t.Elem().(type) {
		case *types.Named:
			g.genFromRefnum(toName, fromName, t, t.Obj())
		default:
			g.errorf("unsupported type %s", t)
		}
	case *types.Named:
		switch t.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			g.genFromRefnum(toName, fromName, t, t.Obj())
		default:
			g.errorf("unsupported, direct named type %s", t)
		}
	default:
		g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName)
	}
}

func (g *JavaGen) genFromRefnum(toName, fromName string, t types.Type, o *types.TypeName) {
	oPkg := o.Pkg()
	isJava := isJavaType(o.Type())
	if !isErrorType(o.Type()) && !g.validPkg(oPkg) && !isJava {
		g.errorf("type %s is defined in package %s, which is not bound", t, oPkg)
		return
	}
	p := pkgPrefix(oPkg)
	g.Printf("jobject %s = go_seq_from_refnum(env, %s, ", toName, fromName)
	if isJava {
		g.Printf("NULL, NULL")
	} else {
		g.Printf("proxy_class_%s_%s, proxy_class_%s_%s_cons", p, o.Name(), p, o.Name())
	}
	g.Printf(");\n")
}

func (g *JavaGen) gobindOpts() string {
	opts := []string{"-lang=java"}
	if g.JavaPkg != "" {
		opts = append(opts, "-javapkg="+g.JavaPkg)
	}
	return strings.Join(opts, " ")
}

var javaNameReplacer = newNameSanitizer([]string{
	"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
	"class", "const", "continue", "default", "do", "double", "else", "enum",
	"extends", "final", "finally", "float", "for", "goto", "if", "implements",
	"import", "instanceof", "int", "interface", "long", "native", "new", "package",
	"private", "protected", "public", "return", "short", "static", "strictfp",
	"super", "switch", "synchronized", "this", "throw", "throws", "transient",
	"try", "void", "volatile", "while", "false", "null", "true"})

func (g *JavaGen) javaPkgName(pkg *types.Package) string {
	return JavaPkgName(g.JavaPkg, pkg)
}

// JavaPkgName returns the Java package name for a Go package
// given a pkg prefix. If the prefix is empty, "go" is used
// instead.
func JavaPkgName(pkgPrefix string, pkg *types.Package) string {
	if pkg == nil {
		return "go"
	}
	s := javaNameReplacer(pkg.Name())
	if pkgPrefix == "" {
		return s
	}
	return pkgPrefix + "." + s
}

func (g *JavaGen) className() string {
	return JavaClassName(g.Pkg)
}

// JavaClassName returns the name of the Java class that
// contains Go package level identifiers.
func JavaClassName(pkg *types.Package) string {
	if pkg == nil {
		return "Universe"
	}
	return javaNameReplacer(strings.Title(pkg.Name()))
}

func (g *JavaGen) genConst(o *types.Const) {
	if _, ok := o.Type().(*types.Basic); !ok {
		g.Printf("// skipped const %s with unsupported type: %T\n\n", o.Name(), o)
		return
	}
	// TODO(hyangah): should const names use upper cases + "_"?
	// TODO(hyangah): check invalid names.
	jType := g.javaType(o.Type())
	val := o.Val().ExactString()
	switch b := o.Type().(*types.Basic); b.Kind() {
	case types.Int64, types.UntypedInt:
		i, exact := constant.Int64Val(o.Val())
		if !exact {
			g.errorf("const value %s for %s cannot be represented as %s", val, o.Name(), jType)
			return
		}
		val = fmt.Sprintf("%dL", i)

	case types.Float32:
		f, _ := constant.Float32Val(o.Val())
		val = fmt.Sprintf("%gf", f)

	case types.Float64, types.UntypedFloat:
		f, _ := constant.Float64Val(o.Val())
		if math.IsInf(f, 0) || math.Abs(f) > math.MaxFloat64 {
			g.errorf("const value %s for %s cannot be represented as %s", val, o.Name(), jType)
			return
		}
		val = fmt.Sprintf("%g", f)
	}
	g.javadoc(g.docs[o.Name()].Doc())
	g.Printf("public static final %s %s = %s;\n", g.javaType(o.Type()), o.Name(), val)
}

func (g *JavaGen) genJNIField(o *types.TypeName, f *types.Var) {
	if t := f.Type(); !g.isSupported(t) {
		g.Printf("// skipped field %s with unsupported type: %T\n\n", o.Name(), t)
		return
	}
	n := java.JNIMangle(g.javaTypeName(o.Name()))
	// setter
	g.Printf("JNIEXPORT void JNICALL\n")
	g.Printf("Java_%s_%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), n, java.JNIMangle(f.Name()), g.jniType(f.Type()))
	g.Indent()
	g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n")
	g.genJavaToC("v", f.Type(), modeRetained)
	g.Printf("proxy%s_%s_%s_Set(o, _v);\n", g.pkgPrefix, o.Name(), f.Name())
	g.genRelease("v", f.Type(), modeRetained)
	g.Outdent()
	g.Printf("}\n\n")

	// getter
	g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(f.Type()))
	g.Printf("Java_%s_%s_get%s(JNIEnv *env, jobject this) {\n", g.jniPkgName(), n, java.JNIMangle(f.Name()))
	g.Indent()
	g.Printf("int32_t o = go_seq_to_refnum_go(env, this);\n")
	g.Printf("%s r0 = ", g.cgoType(f.Type()))
	g.Printf("proxy%s_%s_%s_Get(o);\n", g.pkgPrefix, o.Name(), f.Name())
	g.genCToJava("_r0", "r0", f.Type(), modeRetained)
	g.Printf("return _r0;\n")
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *JavaGen) genJNIVar(o *types.Var) {
	if t := o.Type(); !g.isSupported(t) {
		g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t)
		return
	}
	n := java.JNIMangle(g.javaTypeName(o.Name()))
	// setter
	g.Printf("JNIEXPORT void JNICALL\n")
	g.Printf("Java_%s_%s_set%s(JNIEnv *env, jclass clazz, %s v) {\n", g.jniPkgName(), g.className(), n, g.jniType(o.Type()))
	g.Indent()
	g.genJavaToC("v", o.Type(), modeRetained)
	g.Printf("var_set%s_%s(_v);\n", g.pkgPrefix, o.Name())
	g.genRelease("v", o.Type(), modeRetained)
	g.Outdent()
	g.Printf("}\n\n")

	// getter
	g.Printf("JNIEXPORT %s JNICALL\n", g.jniType(o.Type()))
	g.Printf("Java_%s_%s_get%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), g.className(), n)
	g.Indent()
	g.Printf("%s r0 = ", g.cgoType(o.Type()))
	g.Printf("var_get%s_%s();\n", g.pkgPrefix, o.Name())
	g.genCToJava("_r0", "r0", o.Type(), modeRetained)
	g.Printf("return _r0;\n")
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *JavaGen) genJNIConstructor(f *types.Func, sName string) {
	if !g.isSigSupported(f.Type()) {
		return
	}
	sig := f.Type().(*types.Signature)
	res := sig.Results()

	g.Printf("JNIEXPORT jobject JNICALL\n")
	g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz", g.jniPkgName(), java.JNIMangle(g.javaTypeName(sName)), java.JNIMangle("__"+f.Name()))
	params := sig.Params()
	for i := 0; i < params.Len(); i++ {
		v := params.At(i)
		jt := g.jniType(v.Type())
		g.Printf(", %s %s", jt, g.paramName(params, i))
	}
	g.Printf(") {\n")
	g.Indent()
	for i := 0; i < params.Len(); i++ {
		name := g.paramName(params, i)
		g.genJavaToC(name, params.At(i).Type(), modeTransient)
	}
	// Constructors always return a mandatory *T and an optional error
	if res.Len() == 1 {
		g.Printf("int32_t refnum = proxy%s__%s(", g.pkgPrefix, f.Name())
	} else {
		g.Printf("struct proxy%s__%s_return res = proxy%s__%s(", g.pkgPrefix, f.Name(), g.pkgPrefix, f.Name())
	}
	for i := 0; i < params.Len(); i++ {
		if i > 0 {
			g.Printf(", ")
		}
		g.Printf("_%s", g.paramName(params, i))
	}
	g.Printf(");\n")
	for i := 0; i < params.Len(); i++ {
		g.genRelease(g.paramName(params, i), params.At(i).Type(), modeTransient)
	}
	// Extract multi returns and handle errors
	if res.Len() == 2 {
		g.Printf("int32_t refnum = res.r0;\n")
		g.genCToJava("_err", "res.r1", res.At(1).Type(), modeRetained)
		g.Printf("go_seq_maybe_throw_exception(env, _err);\n")
	}
	// Pass no proxy class so that the Seq.Ref is returned instead.
	g.Printf("return go_seq_from_refnum(env, refnum, NULL, NULL);\n")
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *JavaGen) genJNIFunc(o *types.Func, sName string, jm *java.Func, proxy, isjava bool) {
	if !g.isSigSupported(o.Type()) {
		n := o.Name()
		if sName != "" {
			n = sName + "." + n
		}
		g.Printf("// skipped function %s with unsupported parameter or return types\n\n", n)
		return
	}
	g.genJNIFuncSignature(o, sName, jm, proxy, isjava)

	g.Printf(" {\n")
	g.Indent()
	g.genJNIFuncBody(o, sName, jm, isjava)
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *JavaGen) genJNIFuncBody(o *types.Func, sName string, jm *java.Func, isjava bool) {
	sig := o.Type().(*types.Signature)
	res := sig.Results()
	if sName != "" {
		g.Printf("int32_t o = go_seq_to_refnum_go(env, __this__);\n")
	}
	params := sig.Params()
	first := 0
	if isjava && params.Len() > 0 && params.At(0).Name() == "this" {
		// Start after the implicit this argument.
		first = 1
		g.Printf("int32_t _%s = go_seq_to_refnum(env, __this__);\n", g.paramName(params, 0))
	}
	for i := first; i < params.Len(); i++ {
		name := g.paramName(params, i)
		g.genJavaToC(name, params.At(i).Type(), modeTransient)
	}
	resPrefix := ""
	if res.Len() > 0 {
		if res.Len() == 1 {
			g.Printf("%s r0 = ", g.cgoType(res.At(0).Type()))
		} else {
			resPrefix = "res."
			g.Printf("struct proxy%s_%s_%s_return res = ", g.pkgPrefix, sName, o.Name())
		}
	}
	g.Printf("proxy%s_%s_%s(", g.pkgPrefix, sName, o.Name())
	if sName != "" {
		g.Printf("o")
	}
	// Pass all arguments, including the implicit this argument.
	for i := 0; i < params.Len(); i++ {
		if i > 0 || sName != "" {
			g.Printf(", ")
		}
		g.Printf("_%s", g.paramName(params, i))
	}
	g.Printf(");\n")
	for i := first; i < params.Len(); i++ {
		g.genRelease(g.paramName(params, i), params.At(i).Type(), modeTransient)
	}
	for i := 0; i < res.Len(); i++ {
		tn := fmt.Sprintf("_r%d", i)
		t := res.At(i).Type()
		g.genCToJava(tn, fmt.Sprintf("%sr%d", resPrefix, i), t, modeRetained)
	}
	// Go backwards so that any exception is thrown before
	// the return.
	for i := res.Len() - 1; i >= 0; i-- {
		t := res.At(i).Type()
		if !isErrorType(t) {
			g.Printf("return _r%d;\n", i)
		} else {
			g.Printf("go_seq_maybe_throw_exception(env, _r%d);\n", i)
		}
	}
}

// genRelease cleans up arguments that weren't copied in genJavaToC.
func (g *JavaGen) genRelease(varName string, t types.Type, mode varMode) {
	switch t := t.(type) {
	case *types.Basic:
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				if mode == modeTransient {
					g.Printf("go_seq_release_byte_array(env, %s, _%s.ptr);\n", varName, varName)
				}
			}
		}
	}
}

func (g *JavaGen) genMethodInterfaceProxy(oName string, m *types.Func) {
	if !g.isSigSupported(m.Type()) {
		g.Printf("// skipped method %s with unsupported parameter or return types\n\n", oName)
		return
	}
	sig := m.Type().(*types.Signature)
	params := sig.Params()
	res := sig.Results()
	g.genInterfaceMethodSignature(m, oName, false, g.paramName)
	g.Indent()
	g.Printf("JNIEnv *env = go_seq_push_local_frame(%d);\n", params.Len())
	g.Printf("jobject o = go_seq_from_refnum(env, refnum, proxy_class_%s_%s, proxy_class_%s_%s_cons);\n", g.pkgPrefix, oName, g.pkgPrefix, oName)
	for i := 0; i < params.Len(); i++ {
		pn := g.paramName(params, i)
		g.genCToJava("_"+pn, pn, params.At(i).Type(), modeTransient)
	}
	if res.Len() > 0 && !isErrorType(res.At(0).Type()) {
		t := res.At(0).Type()
		g.Printf("%s res = (*env)->Call%sMethod(env, o, ", g.jniType(t), g.jniCallType(t))
	} else {
		g.Printf("(*env)->CallVoidMethod(env, o, ")
	}
	g.Printf("mid_%s_%s", oName, m.Name())
	for i := 0; i < params.Len(); i++ {
		g.Printf(", _%s", g.paramName(params, i))
	}
	g.Printf(");\n")
	var retName string
	if res.Len() > 0 {
		t := res.At(0).Type()
		if res.Len() == 2 || isErrorType(t) {
			g.Printf("jobject exc = go_seq_get_exception(env);\n")
			errType := types.Universe.Lookup("error").Type()
			g.genJavaToC("exc", errType, modeRetained)
			retName = "_exc"
		}
		if !isErrorType(t) {
			if res.Len() == 2 {
				g.genCRetClear("res", t, "exc")
			}
			g.genJavaToC("res", t, modeRetained)
			retName = "_res"
		}

		if res.Len() > 1 {
			g.Printf("cproxy%s_%s_%s_return sres = {\n", g.pkgPrefix, oName, m.Name())
			g.Printf("	_res, _exc\n")
			g.Printf("};\n")
			retName = "sres"
		}
	}
	g.Printf("go_seq_pop_local_frame(env);\n")
	if retName != "" {
		g.Printf("return %s;\n", retName)
	}
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *JavaGen) GenH() error {
	pkgPath := ""
	if g.Pkg != nil {
		pkgPath = g.Pkg.Path()
	}
	g.Printf(hPreamble, g.gobindOpts(), pkgPath, g.className())
	for _, iface := range g.interfaces {
		g.Printf("extern jclass proxy_class_%s_%s;\n", g.pkgPrefix, iface.obj.Name())
		g.Printf("extern jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name())
		g.Printf("\n")
		for _, m := range iface.summary.callable {
			if !g.isSigSupported(m.Type()) {
				g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
				continue
			}
			g.genInterfaceMethodSignature(m, iface.obj.Name(), true, g.paramName)
			g.Printf("\n")
		}
	}
	for _, s := range g.structs {
		g.Printf("extern jclass proxy_class_%s_%s;\n", g.pkgPrefix, s.obj.Name())
		g.Printf("extern jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, s.obj.Name())
	}
	g.Printf("#endif\n")
	if len(g.err) > 0 {
		return g.err
	}
	return nil
}

func (g *JavaGen) jniCallType(t types.Type) string {
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.Bool, types.UntypedBool:
			return "Boolean"
		case types.Int:
			return "Long"
		case types.Int8, types.Uint8: // types.Byte
			return "Byte"
		case types.Int16:
			return "Short"
		case types.Int32, types.UntypedRune: // types.Rune
			return "Int"
		case types.Int64, types.UntypedInt:
			return "Long"
		case types.Float32:
			return "Float"
		case types.Float64, types.UntypedFloat:
			return "Double"
		case types.String, types.UntypedString:
			return "Object"
		default:
			g.errorf("unsupported basic type: %s", t)
		}
	case *types.Slice:
		return "Object"
	case *types.Pointer:
		if _, ok := t.Elem().(*types.Named); ok {
			return g.jniCallType(t.Elem())
		}
		g.errorf("unsupported pointer to type: %s", t)
	case *types.Named:
		return "Object"
	default:
		return "Object"
	}
	return "TODO"
}

func (g *JavaGen) jniClassSigPrefix(pkg *types.Package) string {
	return strings.Replace(g.javaPkgName(pkg), ".", "/", -1) + "/"
}

func (g *JavaGen) jniSigType(T types.Type) string {
	if isErrorType(T) {
		return "Ljava/lang/Exception;"
	}
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool, types.UntypedBool:
			return "Z"
		case types.Int:
			return "J"
		case types.Int8:
			return "B"
		case types.Int16:
			return "S"
		case types.Int32, types.UntypedRune: // types.Rune
			return "I"
		case types.Int64, types.UntypedInt:
			return "J"
		case types.Uint8: // types.Byte
			return "B"
		case types.Float32:
			return "F"
		case types.Float64, types.UntypedFloat:
			return "D"
		case types.String, types.UntypedString:
			return "Ljava/lang/String;"
		default:
			g.errorf("unsupported basic type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		return "[" + g.jniSigType(T.Elem())
	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.jniSigType(T.Elem())
		}
		g.errorf("unsupported pointer to type: %s", T)
	case *types.Named:
		return "L" + g.jniClassSigPrefix(T.Obj().Pkg()) + g.javaTypeName(T.Obj().Name()) + ";"
	default:
		g.errorf("unsupported jniType: %#+v, %s\n", T, T)
	}
	return "TODO"
}

func (g *JavaGen) GenC() error {
	var pkgName, pkgPath string
	if g.Pkg != nil {
		pkgName = g.Pkg.Name()
		pkgPath = g.Pkg.Path()
	} else {
		pkgName = "universe"
	}
	g.Printf(cPreamble, g.gobindOpts(), pkgPath)
	g.Printf("#include %q\n", pkgName+".h")
	if g.Pkg != nil {
		for _, pkg := range g.Pkg.Imports() {
			if g.validPkg(pkg) {
				g.Printf("#include \"%s.h\"\n", pkg.Name())
			}
		}
	}
	g.Printf("\n")

	for _, iface := range g.interfaces {
		g.Printf("jclass proxy_class_%s_%s;\n", g.pkgPrefix, iface.obj.Name())
		g.Printf("jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, iface.obj.Name())
		for _, m := range iface.summary.callable {
			if !g.isSigSupported(m.Type()) {
				g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
				continue
			}
			g.Printf("static jmethodID mid_%s_%s;\n", iface.obj.Name(), m.Name())
		}
	}
	for _, s := range g.structs {
		g.Printf("jclass proxy_class_%s_%s;\n", g.pkgPrefix, s.obj.Name())
		g.Printf("jmethodID proxy_class_%s_%s_cons;\n", g.pkgPrefix, s.obj.Name())
	}
	g.Printf("\n")
	g.Printf("JNIEXPORT void JNICALL\n")
	g.Printf("Java_%s_%s__1init(JNIEnv *env, jclass _unused) {\n", g.jniPkgName(), java.JNIMangle(g.className()))
	g.Indent()
	g.Printf("jclass clazz;\n")
	for _, s := range g.structs {
		if jinf, ok := g.jstructs[s.obj]; ok {
			// Leave the class and constructor NULL for Java classes with no
			// default constructor.
			if !jinf.genNoargCon {
				continue
			}
		}
		g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(s.obj.Pkg())+g.javaTypeName(s.obj.Name()))
		g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, s.obj.Name())
		g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"<init>\", \"(Lgo/Seq$Ref;)V\");\n", g.pkgPrefix, s.obj.Name())
	}
	for _, iface := range g.interfaces {
		pkg := iface.obj.Pkg()
		g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+JavaClassName(pkg)+"$proxy"+iface.obj.Name())
		g.Printf("proxy_class_%s_%s = (*env)->NewGlobalRef(env, clazz);\n", g.pkgPrefix, iface.obj.Name())
		g.Printf("proxy_class_%s_%s_cons = (*env)->GetMethodID(env, clazz, \"<init>\", \"(Lgo/Seq$Ref;)V\");\n", g.pkgPrefix, iface.obj.Name())
		if isErrorType(iface.obj.Type()) {
			// As a special case, Java Exceptions are passed to Go pretending to implement the Go error interface.
			// To complete the illusion, use the Throwable.getMessage method for proxied calls to the error.Error method.
			g.Printf("clazz = (*env)->FindClass(env, \"java/lang/Throwable\");\n")
			g.Printf("mid_error_Error = (*env)->GetMethodID(env, clazz, \"getMessage\", \"()Ljava/lang/String;\");\n")
			continue
		}
		g.Printf("clazz = (*env)->FindClass(env, %q);\n", g.jniClassSigPrefix(pkg)+g.javaTypeName(iface.obj.Name()))
		for _, m := range iface.summary.callable {
			if !g.isSigSupported(m.Type()) {
				g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", iface.obj.Name(), m.Name())
				continue
			}
			sig := m.Type().(*types.Signature)
			res := sig.Results()
			retSig := "V"
			if res.Len() > 0 {
				if t := res.At(0).Type(); !isErrorType(t) {
					retSig = g.jniSigType(t)
				}
			}
			var jniParams string
			params := sig.Params()
			for i := 0; i < params.Len(); i++ {
				jniParams += g.jniSigType(params.At(i).Type())
			}
			g.Printf("mid_%s_%s = (*env)->GetMethodID(env, clazz, %q, \"(%s)%s\");\n",
				iface.obj.Name(), m.Name(), javaNameReplacer(lowerFirst(m.Name())), jniParams, retSig)
		}
		g.Printf("\n")
	}
	g.Outdent()
	g.Printf("}\n\n")
	for _, f := range g.funcs {
		g.genJNIFunc(f, "", nil, false, false)
	}
	for _, s := range g.structs {
		sName := s.obj.Name()
		cons := g.constructors[s.obj]
		jinf := g.jstructs[s.obj]
		for _, f := range cons {
			g.genJNIConstructor(f, sName)
		}
		if len(cons) == 0 && (jinf == nil || jinf.genNoargCon) {
			g.Printf("JNIEXPORT jobject JNICALL\n")
			g.Printf("Java_%s_%s_%s(JNIEnv *env, jclass clazz) {\n", g.jniPkgName(), java.JNIMangle(g.javaTypeName(sName)), java.JNIMangle("__New"))
			g.Indent()
			g.Printf("int32_t refnum = new_%s_%s();\n", g.pkgPrefix, sName)
			// Pass no proxy class so that the Seq.Ref is returned instead.
			g.Printf("return go_seq_from_refnum(env, refnum, NULL, NULL);\n")
			g.Outdent()
			g.Printf("}\n\n")
		}

		for _, m := range exportedMethodSet(types.NewPointer(s.obj.Type())) {
			var jm *java.Func
			if jinf != nil {
				jm = jinf.lookupMethod(m, g.hasThis(s.obj.Name(), m))
			}
			g.genJNIFunc(m, sName, jm, false, jinf != nil)
		}
		for _, f := range exportedFields(s.t) {
			g.genJNIField(s.obj, f)
		}
	}
	for _, iface := range g.interfaces {
		for _, m := range iface.summary.callable {
			g.genJNIFunc(m, iface.obj.Name(), nil, true, false)
			g.genMethodInterfaceProxy(iface.obj.Name(), m)
		}
	}
	for _, v := range g.vars {
		g.genJNIVar(v)
	}
	if len(g.err) > 0 {
		return g.err
	}
	return nil
}

func (g *JavaGen) GenJava() error {
	pkgPath := ""
	if g.Pkg != nil {
		pkgPath = g.Pkg.Path()
	}
	g.Printf(javaPreamble, g.javaPkgName(g.Pkg), g.className(), g.gobindOpts(), pkgPath)

	g.Printf("public abstract class %s {\n", g.className())
	g.Indent()
	g.Printf("static {\n")
	g.Indent()
	g.Printf("Seq.touch(); // for loading the native library\n")
	if g.Pkg != nil {
		for _, p := range g.Pkg.Imports() {
			if g.validPkg(p) {
				g.Printf("%s.%s.touch();\n", g.javaPkgName(p), JavaClassName(p))
			}
		}
	}
	g.Printf("_init();\n")
	g.Outdent()
	g.Printf("}\n\n")
	g.Printf("private %s() {} // uninstantiable\n\n", g.className())
	g.Printf("// touch is called from other bound packages to initialize this package\n")
	g.Printf("public static void touch() {}\n\n")
	g.Printf("private static native void _init();\n\n")

	for _, iface := range g.interfaces {
		n := iface.obj.Name()
		g.Printf("private static final class proxy%s", n)
		if isErrorType(iface.obj.Type()) {
			g.Printf(" extends Exception")
		}
		g.Printf(" implements Seq.Proxy, %s {\n", g.javaTypeName(n))
		g.Indent()
		g.genProxyImpl("proxy" + n)
		g.Printf("proxy%s(Seq.Ref ref) { this.ref = ref; }\n\n", n)

		if isErrorType(iface.obj.Type()) {
			g.Printf("@Override public String getMessage() { return error(); }\n\n")
		}
		for _, m := range iface.summary.callable {
			if !g.isSigSupported(m.Type()) {
				g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", n, m.Name())
				continue
			}
			g.Printf("public native ")
			g.genFuncSignature(m, nil, false)
		}

		g.Outdent()
		g.Printf("}\n")
	}

	g.Printf("\n")

	for _, c := range g.constants {
		g.genConst(c)
	}
	g.Printf("\n")
	for _, v := range g.vars {
		g.genVar(v)
	}
	for _, f := range g.funcs {
		if !g.isSigSupported(f.Type()) {
			g.Printf("// skipped function %s with unsupported parameter or return types\n\n", f.Name())
			continue
		}
		g.Printf("public static native ")
		g.genFuncSignature(f, nil, false)
	}

	g.Outdent()
	g.Printf("}\n")

	if len(g.err) > 0 {
		return g.err
	}
	return nil
}

// embeddedJavaClasses returns the possible empty list of Java types embedded
// in the given struct type.
func embeddedJavaClasses(t *types.Struct) []string {
	clsSet := make(map[string]struct{})
	var classes []string
	for i := 0; i < t.NumFields(); i++ {
		f := t.Field(i)
		if !f.Exported() {
			continue
		}
		if t := f.Type(); isJavaType(t) {
			cls := classNameFor(t)
			if _, exists := clsSet[cls]; !exists {
				clsSet[cls] = struct{}{}
				classes = append(classes, cls)
			}
		}
	}
	return classes
}

func classNameFor(t types.Type) string {
	obj := t.(*types.Named).Obj()
	pkg := obj.Pkg()
	return strings.Replace(pkg.Path()[len("Java/"):], "/", ".", -1) + "." + obj.Name()
}

func isJavaType(t types.Type) bool {
	return typePkgFirstElem(t) == "Java"
}

const (
	javaPreamble = `// Java class %[1]s.%[2]s is a proxy for talking to a Go program.
//   gobind %[3]s %[4]s
//
// File is generated by gobind. Do not edit.
package %[1]s;

import go.Seq;

`
	cPreamble = `// JNI functions for the Go <=> Java bridge.
//   gobind %[1]s %[2]s
//
// File is generated by gobind. Do not edit.

#include <android/log.h>
#include <stdint.h>
#include "seq.h"
#include "_cgo_export.h"
`

	hPreamble = `// JNI function headers for the Go <=> Java bridge.
//   gobind %[1]s %[2]s
//
// File is generated by gobind. Do not edit.

#ifndef __%[3]s_H__
#define __%[3]s_H__

#include <jni.h>

`
)
