// Java class go.vars.Vars is a proxy for talking to a Go program.
//   gobind -lang=java vars
//
// File is generated by gobind. Do not edit.
package go.vars;

import go.Seq;

public abstract class Vars {
    private Vars() {} // uninstantiable
    
    public static void setABool(boolean v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeBool(v);
        Seq.send("vars.ABool", 1, in, out);
    }
    
    public static boolean getABool() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.ABool", 2, in, out);
        boolean v = out.readBool();
        return v;
    }
    
    public static void setAFloat(double v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeFloat64(v);
        Seq.send("vars.AFloat", 1, in, out);
    }
    
    public static double getAFloat() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AFloat", 2, in, out);
        double v = out.readFloat64();
        return v;
    }
    
    public static void setAFloat32(float v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeFloat32(v);
        Seq.send("vars.AFloat32", 1, in, out);
    }
    
    public static float getAFloat32() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AFloat32", 2, in, out);
        float v = out.readFloat32();
        return v;
    }
    
    public static void setAFloat64(double v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeFloat64(v);
        Seq.send("vars.AFloat64", 1, in, out);
    }
    
    public static double getAFloat64() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AFloat64", 2, in, out);
        double v = out.readFloat64();
        return v;
    }
    
    public static void setAString(String v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeString(v);
        Seq.send("vars.AString", 1, in, out);
    }
    
    public static String getAString() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AString", 2, in, out);
        String v = out.readString();
        return v;
    }
    
    public static void setAStructPtr(S v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeRef(v.ref());
        Seq.send("vars.AStructPtr", 1, in, out);
    }
    
    public static S getAStructPtr() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AStructPtr", 2, in, out);
        S v = new S(out.readRef());
        return v;
    }
    
    public static void setAnInt(long v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeInt(v);
        Seq.send("vars.AnInt", 1, in, out);
    }
    
    public static long getAnInt() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AnInt", 2, in, out);
        long v = out.readInt();
        return v;
    }
    
    public static void setAnInt16(short v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeInt16(v);
        Seq.send("vars.AnInt16", 1, in, out);
    }
    
    public static short getAnInt16() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AnInt16", 2, in, out);
        short v = out.readInt16();
        return v;
    }
    
    public static void setAnInt32(int v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeInt32(v);
        Seq.send("vars.AnInt32", 1, in, out);
    }
    
    public static int getAnInt32() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AnInt32", 2, in, out);
        int v = out.readInt32();
        return v;
    }
    
    public static void setAnInt64(long v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeInt64(v);
        Seq.send("vars.AnInt64", 1, in, out);
    }
    
    public static long getAnInt64() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AnInt64", 2, in, out);
        long v = out.readInt64();
        return v;
    }
    
    public static void setAnInt8(byte v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeInt8(v);
        Seq.send("vars.AnInt8", 1, in, out);
    }
    
    public static byte getAnInt8() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AnInt8", 2, in, out);
        byte v = out.readInt8();
        return v;
    }
    
    public static void setAnInterface(I v) {
        Seq in = new Seq();
        Seq out = new Seq();
        in.writeRef(v.ref());
        Seq.send("vars.AnInterface", 1, in, out);
    }
    
    public static I getAnInterface() {
        Seq in = new Seq();
        Seq out = new Seq();
        Seq.send("vars.AnInterface", 2, in, out);
        I v = new I.Proxy(out.readRef());
        return v;
    }
    
    public interface I extends go.Seq.Object {
        public static abstract class Stub implements I {
            static final String DESCRIPTOR = "go.vars.I";
            
            private final go.Seq.Ref ref;
            public Stub() {
                ref = go.Seq.createRef(this);
            }
            
            public go.Seq.Ref ref() { return ref; }
            
            public void call(int code, go.Seq in, go.Seq out) {
                switch (code) {
                default:
                    throw new RuntimeException("unknown code: "+ code);
                }
            }
        }
        
        static final class Proxy implements I {
            static final String DESCRIPTOR = Stub.DESCRIPTOR;
        
            private go.Seq.Ref ref;
        
            Proxy(go.Seq.Ref ref) { this.ref = ref; }
        
            public go.Seq.Ref ref() { return ref; }
        
            public void call(int code, go.Seq in, go.Seq out) {
                throw new RuntimeException("cycle: cannot call proxy");
            }
        
        }
    }
    
    public static final class S implements go.Seq.Object {
        private static final String DESCRIPTOR = "go.vars.S";
        
        private go.Seq.Ref ref;
        
        private S(go.Seq.Ref ref) { this.ref = ref; }
        
        public go.Seq.Ref ref() { return ref; }
        
        public void call(int code, go.Seq in, go.Seq out) {
            throw new RuntimeException("internal error: cycle: cannot call concrete proxy");
        }
        
        @Override public boolean equals(Object o) {
            if (o == null || !(o instanceof S)) {
                return false;
            }
            S that = (S)o;
            return true;
        }
        
        @Override public int hashCode() {
            return java.util.Arrays.hashCode(new Object[] {});
        }
        
        @Override public String toString() {
            StringBuilder b = new StringBuilder();
            b.append("S").append("{");
            return b.append("}").toString();
        }
        
    }
    
    private static final String DESCRIPTOR = "vars";
}
