// Code generated by gobind. DO NOT EDIT.

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

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

jclass proxy_class_structs_I;
jmethodID proxy_class_structs_I_cons;
static jmethodID mid_I_M;
jclass proxy_class_structs_S;
jmethodID proxy_class_structs_S_cons;
jclass proxy_class_structs_S2;
jmethodID proxy_class_structs_S2_cons;
jclass proxy_class_structs_Structs;
jmethodID proxy_class_structs_Structs_cons;

JNIEXPORT void JNICALL
Java_structs_Structs__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "structs/S");
    proxy_class_structs_S = (*env)->NewGlobalRef(env, clazz);
    proxy_class_structs_S_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "structs/S2");
    proxy_class_structs_S2 = (*env)->NewGlobalRef(env, clazz);
    proxy_class_structs_S2_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "structs/Structs_");
    proxy_class_structs_Structs = (*env)->NewGlobalRef(env, clazz);
    proxy_class_structs_Structs_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "structs/Structs$proxyI");
    proxy_class_structs_I = (*env)->NewGlobalRef(env, clazz);
    proxy_class_structs_I_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "structs/I");
    mid_I_M = (*env)->GetMethodID(env, clazz, "m", "()V");
    
}

JNIEXPORT jobject JNICALL
Java_structs_Structs_identity(JNIEnv* env, jclass _clazz, jobject s) {
    int32_t _s = go_seq_to_refnum(env, s);
    int32_t r0 = proxystructs__Identity(_s);
    jobject _r0 = go_seq_from_refnum(env, r0, proxy_class_structs_S, proxy_class_structs_S_cons);
    return _r0;
}

JNIEXPORT jobject JNICALL
Java_structs_Structs_identityWithError(JNIEnv* env, jclass _clazz, jobject s) {
    int32_t _s = go_seq_to_refnum(env, s);
    struct proxystructs__IdentityWithError_return res = proxystructs__IdentityWithError(_s);
    jobject _r0 = go_seq_from_refnum(env, res.r0, proxy_class_structs_S, proxy_class_structs_S_cons);
    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;
}

JNIEXPORT jint JNICALL
Java_structs_S__1_1New(JNIEnv *env, jclass clazz) {
    return new_structs_S();
}

JNIEXPORT jobject JNICALL
Java_structs_S_identity(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    struct proxystructs_S_Identity_return res = proxystructs_S_Identity(o);
    jobject _r0 = go_seq_from_refnum(env, res.r0, proxy_class_structs_S, proxy_class_structs_S_cons);
    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;
}

JNIEXPORT jdouble JNICALL
Java_structs_S_sum(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    double r0 = proxystructs_S_Sum(o);
    jdouble _r0 = (jdouble)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_structs_S_setX(JNIEnv *env, jobject this, jdouble v) {
    int32_t o = go_seq_to_refnum_go(env, this);
    double _v = (double)v;
    proxystructs_S_X_Set(o, _v);
}

JNIEXPORT jdouble JNICALL
Java_structs_S_getX(JNIEnv *env, jobject this) {
    int32_t o = go_seq_to_refnum_go(env, this);
    double r0 = proxystructs_S_X_Get(o);
    jdouble _r0 = (jdouble)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_structs_S_setY(JNIEnv *env, jobject this, jdouble v) {
    int32_t o = go_seq_to_refnum_go(env, this);
    double _v = (double)v;
    proxystructs_S_Y_Set(o, _v);
}

JNIEXPORT jdouble JNICALL
Java_structs_S_getY(JNIEnv *env, jobject this) {
    int32_t o = go_seq_to_refnum_go(env, this);
    double r0 = proxystructs_S_Y_Get(o);
    jdouble _r0 = (jdouble)r0;
    return _r0;
}

JNIEXPORT jint JNICALL
Java_structs_S2__1_1New(JNIEnv *env, jclass clazz) {
    return new_structs_S2();
}

JNIEXPORT void JNICALL
Java_structs_S2_m(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    proxystructs_S2_M(o);
}

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

JNIEXPORT jint JNICALL
Java_structs_Structs_1__1_1New(JNIEnv *env, jclass clazz) {
    return new_structs_Structs();
}

JNIEXPORT void JNICALL
Java_structs_Structs_1_m(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    proxystructs_Structs_M(o);
}

JNIEXPORT void JNICALL
Java_structs_Structs_00024proxyI_m(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    proxystructs_I_M(o);
}

void cproxystructs_I_M(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_structs_I, proxy_class_structs_I_cons);
    (*env)->CallVoidMethod(env, o, mid_I_M);
    go_seq_pop_local_frame(env);
}

