// Code generated by gobind. DO NOT EDIT.

// Java class issue10788.TestStruct is a proxy for talking to a Go program.
//
//   autogenerated by gobind -lang=java issue10788
package issue10788;

import go.Seq;

public final class TestStruct implements Seq.Proxy {
    static { Issue10788.touch(); }
    
    private final int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    TestStruct(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
    
    public TestStruct() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
    
    private static native int __New();
    
    public final native String getValue();
    public final native void setValue(String v);
    
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof TestStruct)) {
            return false;
        }
        TestStruct that = (TestStruct)o;
        String thisValue = getValue();
        String thatValue = that.getValue();
        if (thisValue == null) {
            if (thatValue != null) {
                return false;
            }
        } else if (!thisValue.equals(thatValue)) {
            return false;
        }
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {getValue()});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("TestStruct").append("{");
        b.append("Value:").append(getValue()).append(",");
        return b.append("}").toString();
    }
}

// Code generated by gobind. DO NOT EDIT.

// Java class issue10788.TestInterface is a proxy for talking to a Go program.
//
//   autogenerated by gobind -lang=java issue10788
package issue10788;

import go.Seq;

public interface TestInterface {
    public void doSomeWork(TestStruct s);
    public void multipleUnnamedParams(long p0, String p1, long p2);
    
}

// Code generated by gobind. DO NOT EDIT.

// Java class issue10788.Issue10788 is a proxy for talking to a Go program.
//
//   autogenerated by gobind -lang=java issue10788
package issue10788;

import go.Seq;

public abstract class Issue10788 {
    static {
        Seq.touch(); // for loading the native library
        _init();
    }
    
    private Issue10788() {} // uninstantiable
    
    // touch is called from other bound packages to initialize this package
    public static void touch() {}
    
    private static native void _init();
    
    private static final class proxyTestInterface implements Seq.Proxy, TestInterface {
        private final int refnum;
        
        @Override public final int incRefnum() {
              Seq.incGoRef(refnum, this);
              return refnum;
        }
        
        proxyTestInterface(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
        
        public native void doSomeWork(TestStruct s);
        public native void multipleUnnamedParams(long p0, String p1, long p2);
    }
    
    
}
