// Code generated by gobind. DO NOT EDIT.

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

#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>", "(I)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>", "(I)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>", "(I)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>", "(I)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 jint JNICALL
Java_doc_NoDoc__1_1New(JNIEnv *env, jclass clazz) {
    return new_doc_NoDoc();
}

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

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 jint JNICALL
Java_doc_S2__1_1New(JNIEnv *env, jclass clazz) {
    return new_doc_S2();
}

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

