// 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"
	"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, s.obj.Name())
	}
	for _, iface := range g.interfaces {
		names = append(names, 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 := 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, 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 {
				n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n)
			}
			impls = append(impls, n)
		}
	}

	g.Printf("public final class %s", n)
	if jinf != nil {
		if jinf.extends != nil {
			g.Printf(" extends %s", 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
		}
		g.Printf("public final native %s get%s();\n", g.javaType(f.Type()), f.Name())
		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
		}
		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")
}

// 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.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), 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 {
				n = fmt.Sprintf("%s.%s", g.javaPkgName(p), n)
			}
			exts = append(exts, n)
		}
	}
	g.Printf("public interface %s", 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.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
		if nPkg != g.Pkg {
			return fmt.Sprintf("%s.%s", g.javaPkgName(nPkg), n.Name())
		} else {
			return n.Name()
		}
	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("_00024")
			g.Printf("proxy")
		}
		g.Printf("%s", sName)
	} else {
		g.Printf(g.className())
	}
	g.Printf("_")
	if jm != nil {
		g.Printf(jm.JNIName)
	} else {
		oName := javaNameReplacer(lowerFirst(o.Name()))
		if strings.HasSuffix(oName, "_") {
			oName += "1" // JNI doesn't like methods ending with underscore, needs the _1 suffixing
		}
		g.Printf(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(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())

	// setter
	g.Printf("public static native void set%s(%s v);\n", o.Name(), jType)

	// getter
	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 := constExactString(o)
	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.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
	}
	// setter
	g.Printf("JNIEXPORT void JNICALL\n")
	g.Printf("Java_%s_%s_set%s(JNIEnv *env, jobject this, %s v) {\n", g.jniPkgName(), o.Name(), 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(), o.Name(), 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
	}
	// 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(), o.Name(), 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(), o.Name())
	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(), 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()) + 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(), 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())+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)+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(), 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", 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>

`
)
