// 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

@implementation GoVars
+ (void) 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) ABool {
	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) 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) AFloat {
	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) 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) AFloat32 {
	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) 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) AFloat64 {
	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) 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*) AString {
	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) 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*) AStructPtr {
	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) 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) AnInt {
	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) 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) AnInt16 {
	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) 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) AnInt32 {
	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) 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) AnInt64 {
	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) 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) AnInt8 {
	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) 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>) AnInterface {
	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;
}

@end

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