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

import go.Seq;

public abstract class Basictypes {
    private Basictypes() {} // uninstantiable
    
    public static boolean Bool(boolean p0) {
        go.Seq _in = new go.Seq();
        go.Seq _out = new go.Seq();
        boolean _result;
        _in.writeBool(p0);
        Seq.send(DESCRIPTOR, CALL_Bool, _in, _out);
        _result = _out.readBool();
        return _result;
    }
    
    public static byte[] ByteArrays(byte[] x) {
        go.Seq _in = new go.Seq();
        go.Seq _out = new go.Seq();
        byte[] _result;
        _in.writeByteArray(x);
        Seq.send(DESCRIPTOR, CALL_ByteArrays, _in, _out);
        _result = _out.readByteArray();
        return _result;
    }
    
    public static void Error() throws Exception {
        go.Seq _in = new go.Seq();
        go.Seq _out = new go.Seq();
        Seq.send(DESCRIPTOR, CALL_Error, _in, _out);
        String _err = _out.readString();
        if (_err != null) {
            throw new Exception(_err);
        }
    }
    
    public static long ErrorPair() throws Exception {
        go.Seq _in = new go.Seq();
        go.Seq _out = new go.Seq();
        long _result;
        Seq.send(DESCRIPTOR, CALL_ErrorPair, _in, _out);
        _result = _out.readInt();
        String _err = _out.readString();
        if (_err != null) {
            throw new Exception(_err);
        }
        return _result;
    }
    
    public static void Ints(byte x, short y, int z, long t, long u) {
        go.Seq _in = new go.Seq();
        go.Seq _out = new go.Seq();
        _in.writeInt8(x);
        _in.writeInt16(y);
        _in.writeInt32(z);
        _in.writeInt64(t);
        _in.writeInt(u);
        Seq.send(DESCRIPTOR, CALL_Ints, _in, _out);
    }
    
    private static final int CALL_Bool = 1;
    private static final int CALL_ByteArrays = 2;
    private static final int CALL_Error = 3;
    private static final int CALL_ErrorPair = 4;
    private static final int CALL_Ints = 5;
    private static final String DESCRIPTOR = "basictypes";
}
