// Code generated by gobind. DO NOT EDIT.

// JNI functions for the Go <=> Java bridge.
//
//   autogenerated by gobind -lang=java issue12403

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

jclass proxy_class_issue12403_Parsable;
jmethodID proxy_class_issue12403_Parsable_cons;
static jmethodID mid_Parsable_FromJSON;
static jmethodID mid_Parsable_ToJSON;

JNIEXPORT void JNICALL
Java_issue12403_Issue12403__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "issue12403/Issue12403$proxyParsable");
    proxy_class_issue12403_Parsable = (*env)->NewGlobalRef(env, clazz);
    proxy_class_issue12403_Parsable_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "issue12403/Parsable");
    mid_Parsable_FromJSON = (*env)->GetMethodID(env, clazz, "fromJSON", "(Ljava/lang/String;)Ljava/lang/String;");
    mid_Parsable_ToJSON = (*env)->GetMethodID(env, clazz, "toJSON", "()Ljava/lang/String;");
    
}

JNIEXPORT jstring JNICALL
Java_issue12403_Issue12403_00024proxyParsable_fromJSON(JNIEnv* env, jobject __this__, jstring jstr) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    nstring _jstr = go_seq_from_java_string(env, jstr);
    nstring r0 = proxyissue12403_Parsable_FromJSON(o, _jstr);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

nstring cproxyissue12403_Parsable_FromJSON(int32_t refnum, nstring jstr) {
    JNIEnv *env = go_seq_push_local_frame(1);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_issue12403_Parsable, proxy_class_issue12403_Parsable_cons);
    jstring _jstr = go_seq_to_java_string(env, jstr);
    jstring res = (*env)->CallObjectMethod(env, o, mid_Parsable_FromJSON, _jstr);
    nstring _res = go_seq_from_java_string(env, res);
    go_seq_pop_local_frame(env);
    return _res;
}

JNIEXPORT jstring JNICALL
Java_issue12403_Issue12403_00024proxyParsable_toJSON(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    struct proxyissue12403_Parsable_ToJSON_return res = proxyissue12403_Parsable_ToJSON(o);
    jstring _r0 = go_seq_to_java_string(env, res.r0);
    jobject _r1 = go_seq_from_refnum(env, res.r1, proxy_class__error, proxy_class__error_cons);
    go_seq_maybe_throw_exception(env, _r1);
    return _r0;
}

struct cproxyissue12403_Parsable_ToJSON_return cproxyissue12403_Parsable_ToJSON(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_issue12403_Parsable, proxy_class_issue12403_Parsable_cons);
    jstring res = (*env)->CallObjectMethod(env, o, mid_Parsable_ToJSON);
    jobject exc = go_seq_get_exception(env);
    int32_t _exc = go_seq_to_refnum(env, exc);
    if (exc != NULL) {
        res = NULL;
    }
    nstring _res = go_seq_from_java_string(env, res);
    cproxyissue12403_Parsable_ToJSON_return sres = {
    	_res, _exc
    };
    go_seq_pop_local_frame(env);
    return sres;
}

