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

#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;

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>", "(Lgo/Seq$Ref;)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>", "(Lgo/Seq$Ref;)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>", "(Lgo/Seq$Ref;)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 jobject JNICALL
Java_structs_S__1_1New(JNIEnv *env, jclass clazz) {
    int32_t refnum = new_structs_S();
    return go_seq_from_refnum(env, refnum, NULL, NULL);
}

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 jobject JNICALL
Java_structs_S2__1_1New(JNIEnv *env, jclass clazz) {
    int32_t refnum = new_structs_S2();
    return go_seq_from_refnum(env, refnum, NULL, NULL);
}

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 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);
}

