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

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

jclass proxy_class_doc_I;
jmethodID proxy_class_doc_I_cons;
static jmethodID mid_I_IM;
jclass proxy_class_doc_NoDoc;
jmethodID proxy_class_doc_NoDoc_cons;
jclass proxy_class_doc_S;
jmethodID proxy_class_doc_S_cons;
jclass proxy_class_doc_S2;
jmethodID proxy_class_doc_S2_cons;

JNIEXPORT void JNICALL
Java_doc_Doc__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "doc/NoDoc");
    proxy_class_doc_NoDoc = (*env)->NewGlobalRef(env, clazz);
    proxy_class_doc_NoDoc_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
    clazz = (*env)->FindClass(env, "doc/S");
    proxy_class_doc_S = (*env)->NewGlobalRef(env, clazz);
    proxy_class_doc_S_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
    clazz = (*env)->FindClass(env, "doc/S2");
    proxy_class_doc_S2 = (*env)->NewGlobalRef(env, clazz);
    proxy_class_doc_S2_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
    clazz = (*env)->FindClass(env, "doc/Doc$proxyI");
    proxy_class_doc_I = (*env)->NewGlobalRef(env, clazz);
    proxy_class_doc_I_cons = (*env)->GetMethodID(env, clazz, "<init>", "(Lgo/Seq$Ref;)V");
    clazz = (*env)->FindClass(env, "doc/I");
    mid_I_IM = (*env)->GetMethodID(env, clazz, "im", "()V");
    
}

JNIEXPORT void JNICALL
Java_doc_Doc_f(JNIEnv* env, jclass _clazz) {
    proxydoc__F();
}

JNIEXPORT jobject JNICALL
Java_doc_Doc_newS(JNIEnv* env, jclass _clazz) {
    int32_t r0 = proxydoc__NewS();
    jobject _r0 = go_seq_from_refnum(env, r0, proxy_class_doc_S, proxy_class_doc_S_cons);
    return _r0;
}

JNIEXPORT jobject JNICALL
Java_doc_NoDoc__1_1New(JNIEnv *env, jclass clazz) {
    int32_t refnum = new_doc_NoDoc();
    return go_seq_from_refnum(env, refnum, NULL, NULL);
}

JNIEXPORT jobject JNICALL
Java_doc_S__1_1NewS(JNIEnv *env, jclass clazz) {
    int32_t refnum = proxydoc__NewS();
    return go_seq_from_refnum(env, refnum, NULL, NULL);
}

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

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

JNIEXPORT void JNICALL
Java_doc_S_setSF(JNIEnv *env, jobject this, jstring v) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring _v = go_seq_from_java_string(env, v);
    proxydoc_S_SF_Set(o, _v);
}

JNIEXPORT jstring JNICALL
Java_doc_S_getSF(JNIEnv *env, jobject this) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring r0 = proxydoc_S_SF_Get(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

JNIEXPORT void JNICALL
Java_doc_S_setS2(JNIEnv *env, jobject this, jobject v) {
    int32_t o = go_seq_to_refnum_go(env, this);
    int32_t _v = go_seq_to_refnum(env, v);
    proxydoc_S_S2_Set(o, _v);
}

JNIEXPORT jobject JNICALL
Java_doc_S_getS2(JNIEnv *env, jobject this) {
    int32_t o = go_seq_to_refnum_go(env, this);
    int32_t r0 = proxydoc_S_S2_Get(o);
    jobject _r0 = go_seq_from_refnum(env, r0, proxy_class_doc_S2, proxy_class_doc_S2_cons);
    return _r0;
}

JNIEXPORT void JNICALL
Java_doc_S_setF1(JNIEnv *env, jobject this, jstring v) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring _v = go_seq_from_java_string(env, v);
    proxydoc_S_F1_Set(o, _v);
}

JNIEXPORT jstring JNICALL
Java_doc_S_getF1(JNIEnv *env, jobject this) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring r0 = proxydoc_S_F1_Get(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

JNIEXPORT void JNICALL
Java_doc_S_setF2(JNIEnv *env, jobject this, jstring v) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring _v = go_seq_from_java_string(env, v);
    proxydoc_S_F2_Set(o, _v);
}

JNIEXPORT jstring JNICALL
Java_doc_S_getF2(JNIEnv *env, jobject this) {
    int32_t o = go_seq_to_refnum_go(env, this);
    nstring r0 = proxydoc_S_F2_Get(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

JNIEXPORT jobject JNICALL
Java_doc_S2__1_1New(JNIEnv *env, jclass clazz) {
    int32_t refnum = new_doc_S2();
    return go_seq_from_refnum(env, refnum, NULL, NULL);
}

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

void cproxydoc_I_IM(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_doc_I, proxy_class_doc_I_cons);
    (*env)->CallVoidMethod(env, o, mid_I_IM);
    go_seq_pop_local_frame(env);
}

JNIEXPORT void JNICALL
Java_doc_Doc_setNoDocVar(JNIEnv *env, jclass clazz, jdouble v) {
    double _v = (double)v;
    var_setdoc_NoDocVar(_v);
}

JNIEXPORT jdouble JNICALL
Java_doc_Doc_getNoDocVar(JNIEnv *env, jclass clazz) {
    double r0 = var_getdoc_NoDocVar();
    jdouble _r0 = (jdouble)r0;
    return _r0;
}

JNIEXPORT void JNICALL
Java_doc_Doc_setSpecific(JNIEnv *env, jclass clazz, jstring v) {
    nstring _v = go_seq_from_java_string(env, v);
    var_setdoc_Specific(_v);
}

JNIEXPORT jstring JNICALL
Java_doc_Doc_getSpecific(JNIEnv *env, jclass clazz) {
    nstring r0 = var_getdoc_Specific();
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

JNIEXPORT void JNICALL
Java_doc_Doc_setV(JNIEnv *env, jclass clazz, jstring v) {
    nstring _v = go_seq_from_java_string(env, v);
    var_setdoc_V(_v);
}

JNIEXPORT jstring JNICALL
Java_doc_Doc_getV(JNIEnv *env, jclass clazz) {
    nstring r0 = var_getdoc_V();
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

