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

import go.Seq;

/**
 * A generic comment with &lt;HTML&gt;.
 */
public final class NoDoc implements Seq.Proxy {
    static { Doc.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    NoDoc(Seq.Ref ref) { this.ref = ref; }
    
    public NoDoc() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof NoDoc)) {
            return false;
        }
        NoDoc that = (NoDoc)o;
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("NoDoc").append("{");
        return b.append("}").toString();
    }
}

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

import go.Seq;

/**
 * S is a struct.
 */
public final class S implements Seq.Proxy {
    static { Doc.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    /**
     * NewS is a constructor.
     */
    public S() {
        this.ref = __NewS();
    }
    
    private static native Seq.Ref __NewS();
    
    S(Seq.Ref ref) { this.ref = ref; }
    
    /**
     * SF is a field.
     */
    public final native String getSF();
    /**
     * SF is a field.
     */
    public final native void setSF(String v);
    
    /**
     * Anonymous field.
     */
    public final native S2 getS2();
    /**
     * Anonymous field.
     */
    public final native void setS2(S2 v);
    
    /**
     * Multiple fields.
     */
    public final native String getF1();
    /**
     * Multiple fields.
     */
    public final native void setF1(String v);
    
    /**
     * Multiple fields.
     */
    public final native String getF2();
    /**
     * Multiple fields.
     */
    public final native void setF2(String v);
    
    /**
     * After is another method.
     */
    public native void after();
    public native void before();
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof S)) {
            return false;
        }
        S that = (S)o;
        String thisSF = getSF();
        String thatSF = that.getSF();
        if (thisSF == null) {
            if (thatSF != null) {
                return false;
            }
        } else if (!thisSF.equals(thatSF)) {
            return false;
        }
        S2 thisS2 = getS2();
        S2 thatS2 = that.getS2();
        if (thisS2 == null) {
            if (thatS2 != null) {
                return false;
            }
        } else if (!thisS2.equals(thatS2)) {
            return false;
        }
        String thisF1 = getF1();
        String thatF1 = that.getF1();
        if (thisF1 == null) {
            if (thatF1 != null) {
                return false;
            }
        } else if (!thisF1.equals(thatF1)) {
            return false;
        }
        String thisF2 = getF2();
        String thatF2 = that.getF2();
        if (thisF2 == null) {
            if (thatF2 != null) {
                return false;
            }
        } else if (!thisF2.equals(thatF2)) {
            return false;
        }
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {getSF(), getS2(), getF1(), getF2()});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("S").append("{");
        b.append("SF:").append(getSF()).append(",");
        b.append("S2:").append(getS2()).append(",");
        b.append("F1:").append(getF1()).append(",");
        b.append("F2:").append(getF2()).append(",");
        return b.append("}").toString();
    }
}

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

import go.Seq;

/**
 * S2 is a struct.
 */
public final class S2 implements Seq.Proxy {
    static { Doc.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    S2(Seq.Ref ref) { this.ref = ref; }
    
    public S2() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof S2)) {
            return false;
        }
        S2 that = (S2)o;
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("S2").append("{");
        return b.append("}").toString();
    }
}

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

import go.Seq;

/**
 * I is an interface.
 */
public interface I {
    /**
     * IM is a method.
     */
    public void im();
    
}

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

import go.Seq;

public abstract class Doc {
    static {
        Seq.touch(); // for loading the native library
        _init();
    }
    
    private Doc() {} // 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 proxyI implements Seq.Proxy, I {
        private final Seq.Ref ref;
        
        @Override public final int incRefnum() {
              int refnum = ref.refnum;
              Seq.incGoRef(refnum);
              return refnum;
        }
        
        proxyI(Seq.Ref ref) { this.ref = ref; }
        
        public native void im();
    }
    
    /**
     * C is a constant.
     */
    public static final boolean C = true;
    
    /**
     * A group of vars.
     */
    public static native void setNoDocVar(double v);
    /**
     * A group of vars.
     */
    public static native double getNoDocVar();
    
    /**
     * A specific var.
     */
    public static native void setSpecific(String v);
    /**
     * A specific var.
     */
    public static native String getSpecific();
    
    /**
     * V is a var.
     */
    public static native void setV(String v);
    /**
     * V is a var.
     */
    public static native String getV();
    
    public static native void f();
    public static native S newS();
}
