// Objective-C API for talking to vars Go package.
//   gobind -lang=objc vars
//
// File is generated by gobind. Do not edit.

#include "GoVars.h"
#include <Foundation/Foundation.h>
#include "seq.h"

static NSString* errDomain = @"go.vars";

@protocol goSeqRefInterface
-(GoSeqRef*) ref;
@end

#define _DESCRIPTOR_ "vars"


#define _GO_vars_I_DESCRIPTOR_ "go.vars.I"

@interface GoVarsI : NSObject <GoVarsI> {
}
@property(strong, readonly) id ref;

- (id)initWithRef:(id)ref;
@end

@implementation GoVarsI {
}

- (id)initWithRef:(id)ref {
	self = [super init];
	if (self) { _ref = ref; }
	return self;
}

@end

static void proxyGoVarsI(id obj, int code, GoSeq* in, GoSeq* out) {
	switch (code) {
	default:
		NSLog(@"unknown code %x for _GO_vars_I_DESCRIPTOR_", code);
	}
}

#define _GO_vars_S_DESCRIPTOR_ "go.vars.S"

@implementation GoVarsS {
}

- (id)initWithRef:(id)ref {
	self = [super init];
	if (self) { _ref = ref; }
	return self;
}

@end

void GoVars_setABool(BOOL v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeBool(&in_, v);
	go_seq_send("vars.ABool", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

BOOL GoVarsABool() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.ABool", 2, &in_, &out_);
	BOOL ret = go_seq_readBool(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAFloat(double v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeFloat64(&in_, v);
	go_seq_send("vars.AFloat", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

double GoVarsAFloat() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AFloat", 2, &in_, &out_);
	double ret = go_seq_readFloat64(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAFloat32(float v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeFloat32(&in_, v);
	go_seq_send("vars.AFloat32", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

float GoVarsAFloat32() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AFloat32", 2, &in_, &out_);
	float ret = go_seq_readFloat32(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAFloat64(double v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeFloat64(&in_, v);
	go_seq_send("vars.AFloat64", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

double GoVarsAFloat64() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AFloat64", 2, &in_, &out_);
	double ret = go_seq_readFloat64(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAString(NSString* v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeUTF8(&in_, v);
	go_seq_send("vars.AString", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

NSString* GoVarsAString() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AString", 2, &in_, &out_);
	NSString* ret = go_seq_readUTF8(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAStructPtr(GoVarsS* v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	if ([(id<NSObject>)(v) isKindOfClass:[GoVarsS class]]) {
		id<goSeqRefInterface> v_proxy = (id<goSeqRefInterface>)(v);
		go_seq_writeRef(&in_, v_proxy.ref);
	} else {
		go_seq_writeObjcRef(&in_, v);
	}
	go_seq_send("vars.AStructPtr", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

GoVarsS* GoVarsAStructPtr() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AStructPtr", 2, &in_, &out_);
	GoSeqRef* ret_ref = go_seq_readRef(&out_);
	GoVarsS* ret = ret_ref.obj;
	if (ret == NULL) {
		ret = [[GoVarsS alloc] initWithRef:ret_ref];
	}
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAnInt(int v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeInt(&in_, v);
	go_seq_send("vars.AnInt", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

int GoVarsAnInt() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AnInt", 2, &in_, &out_);
	int ret = go_seq_readInt(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAnInt16(int16_t v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeInt16(&in_, v);
	go_seq_send("vars.AnInt16", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

int16_t GoVarsAnInt16() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AnInt16", 2, &in_, &out_);
	int16_t ret = go_seq_readInt16(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAnInt32(int32_t v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeInt32(&in_, v);
	go_seq_send("vars.AnInt32", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

int32_t GoVarsAnInt32() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AnInt32", 2, &in_, &out_);
	int32_t ret = go_seq_readInt32(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAnInt64(int64_t v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeInt64(&in_, v);
	go_seq_send("vars.AnInt64", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

int64_t GoVarsAnInt64() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AnInt64", 2, &in_, &out_);
	int64_t ret = go_seq_readInt64(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAnInt8(int8_t v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_writeInt8(&in_, v);
	go_seq_send("vars.AnInt8", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

int8_t GoVarsAnInt8() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AnInt8", 2, &in_, &out_);
	int8_t ret = go_seq_readInt8(&out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}

void GoVars_setAnInterface(id<GoVarsI> v) {
	GoSeq in_ = {};
	GoSeq out_ = {};
	if ([(id<NSObject>)(v) isKindOfClass:[GoVarsI class]]) {
		id<goSeqRefInterface> v_proxy = (id<goSeqRefInterface>)(v);
		go_seq_writeRef(&in_, v_proxy.ref);
	} else {
		go_seq_writeObjcRef(&in_, v);
	}
	go_seq_send("vars.AnInterface", 1, &in_, &out_);
	go_seq_free(&in_);
	go_seq_free(&out_);
}

id<GoVarsI> GoVarsAnInterface() {
	GoSeq in_ = {};
	GoSeq out_ = {};
	go_seq_send("vars.AnInterface", 2, &in_, &out_);
	GoSeqRef* ret_ref = go_seq_readRef(&out_);
	id<GoVarsI> ret = ret_ref.obj;
	if (ret == NULL) {
		ret = [[GoVarsI alloc] initWithRef:ret_ref];
	}
	go_seq_free(&in_);
	go_seq_free(&out_);
	return ret;
}


__attribute__((constructor)) static void init() {
	go_seq_register_proxy("go.vars.I", proxyGoVarsI);
}
