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