// File is generated by gobind. Do not edit.

#include <jni.h>
#include "seq.h"
#include "classes.h"

static jclass class_java_lang_Float;
static jmethodID m_java_lang_Float_toString;
static jclass class_java_lang_Long;
static jmethodID m_java_lang_Long_toString;
static jclass class_java_lang_Object;
static jmethodID m_java_lang_Object_toString;
static jclass class_java_lang_Runnable;

void init_proxies() {
	JNIEnv *env = go_seq_push_local_frame(4);
	jclass clazz;
	clazz = go_seq_find_class("java/lang/Float");
	if (clazz != NULL) {
		class_java_lang_Float = (*env)->NewGlobalRef(env, clazz);
		m_java_lang_Float_toString = go_seq_get_method_id(clazz, "toString", "()Ljava/lang/String;");
	}
	clazz = go_seq_find_class("java/lang/Long");
	if (clazz != NULL) {
		class_java_lang_Long = (*env)->NewGlobalRef(env, clazz);
		m_java_lang_Long_toString = go_seq_get_method_id(clazz, "toString", "()Ljava/lang/String;");
	}
	clazz = go_seq_find_class("java/lang/Object");
	if (clazz != NULL) {
		class_java_lang_Object = (*env)->NewGlobalRef(env, clazz);
		m_java_lang_Object_toString = go_seq_get_method_id(clazz, "toString", "()Ljava/lang/String;");
	}
	clazz = go_seq_find_class("java/lang/Runnable");
	if (clazz != NULL) {
		class_java_lang_Runnable = (*env)->NewGlobalRef(env, clazz);
	}
	go_seq_pop_local_frame(env);
}

ret_nstring cproxy_java_lang_Float_toString(jint this) {
	JNIEnv *env = go_seq_push_local_frame(1);
	// Must be a Java object
	jobject _this = go_seq_from_refnum(env, this, NULL, NULL);
	jstring res = (*env)->CallObjectMethod(env, _this, m_java_lang_Float_toString);
	jobject _exc = go_seq_get_exception(env);
	int32_t _exc_ref = go_seq_to_refnum(env, _exc);
	if (_exc != NULL) {
		res = NULL;
	}
	nstring _res = go_seq_from_java_string(env, res);
	go_seq_pop_local_frame(env);
	ret_nstring __res = {_res, _exc_ref};
	return __res;
}

ret_nstring cproxy_java_lang_Long_toString(jint this) {
	JNIEnv *env = go_seq_push_local_frame(1);
	// Must be a Java object
	jobject _this = go_seq_from_refnum(env, this, NULL, NULL);
	jstring res = (*env)->CallObjectMethod(env, _this, m_java_lang_Long_toString);
	jobject _exc = go_seq_get_exception(env);
	int32_t _exc_ref = go_seq_to_refnum(env, _exc);
	if (_exc != NULL) {
		res = NULL;
	}
	nstring _res = go_seq_from_java_string(env, res);
	go_seq_pop_local_frame(env);
	ret_nstring __res = {_res, _exc_ref};
	return __res;
}

ret_nstring cproxy_java_lang_Object_toString(jint this) {
	JNIEnv *env = go_seq_push_local_frame(1);
	// Must be a Java object
	jobject _this = go_seq_from_refnum(env, this, NULL, NULL);
	jstring res = (*env)->CallObjectMethod(env, _this, m_java_lang_Object_toString);
	jobject _exc = go_seq_get_exception(env);
	int32_t _exc_ref = go_seq_to_refnum(env, _exc);
	if (_exc != NULL) {
		res = NULL;
	}
	nstring _res = go_seq_from_java_string(env, res);
	go_seq_pop_local_frame(env);
	ret_nstring __res = {_res, _exc_ref};
	return __res;
}

// JNI functions for the Go <=> Java bridge.
//   gobind -lang=java java
//
// File is generated by gobind. Do not edit.

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

jclass proxy_class_java_F;
jmethodID proxy_class_java_F_cons;
static jmethodID mid_F_ToString;
jclass proxy_class_java_L;
jmethodID proxy_class_java_L_cons;
static jmethodID mid_L_ToString;
jclass proxy_class_java_O;
jmethodID proxy_class_java_O_cons;
static jmethodID mid_O_ToString;
jclass proxy_class_java_R;
jmethodID proxy_class_java_R_cons;

JNIEXPORT void JNICALL
Java_java_Java__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "java/Java$proxyF");
    proxy_class_java_F = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_F_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/F");
    mid_F_ToString = (*env)->GetMethodID(env, clazz, "toString", "()Ljava/lang/String;");
    
    clazz = (*env)->FindClass(env, "java/Java$proxyL");
    proxy_class_java_L = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_L_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/L");
    mid_L_ToString = (*env)->GetMethodID(env, clazz, "toString", "()Ljava/lang/String;");
    
    clazz = (*env)->FindClass(env, "java/Java$proxyO");
    proxy_class_java_O = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_O_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/O");
    mid_O_ToString = (*env)->GetMethodID(env, clazz, "toString", "()Ljava/lang/String;");
    
    clazz = (*env)->FindClass(env, "java/Java$proxyR");
    proxy_class_java_R = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_R_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/R");
    
}

JNIEXPORT jstring JNICALL
Java_java_Java_00024proxyF_toString(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    nstring r0 = proxyjava_F_ToString(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

nstring cproxyjava_F_ToString(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_java_F, proxy_class_java_F_cons);
    jstring res = (*env)->CallObjectMethod(env, o, mid_F_ToString);
    nstring _res = go_seq_from_java_string(env, res);
    go_seq_pop_local_frame(env);
    return _res;
}

JNIEXPORT jstring JNICALL
Java_java_Java_00024proxyL_toString(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    nstring r0 = proxyjava_L_ToString(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

nstring cproxyjava_L_ToString(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_java_L, proxy_class_java_L_cons);
    jstring res = (*env)->CallObjectMethod(env, o, mid_L_ToString);
    nstring _res = go_seq_from_java_string(env, res);
    go_seq_pop_local_frame(env);
    return _res;
}

JNIEXPORT jstring JNICALL
Java_java_Java_00024proxyO_toString(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    nstring r0 = proxyjava_O_ToString(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

nstring cproxyjava_O_ToString(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_java_O, proxy_class_java_O_cons);
    jstring res = (*env)->CallObjectMethod(env, o, mid_O_ToString);
    nstring _res = go_seq_from_java_string(env, res);
    go_seq_pop_local_frame(env);
    return _res;
}

