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

import go.Seq;

public abstract class Issue12403 {
    private Issue12403() {} // uninstantiable
    
    public interface Parsable extends go.Seq.Object {
        public String FromJSON(String jstr);
        
        public String ToJSON() throws Exception;
        
        public static abstract class Stub implements Parsable {
            static final String DESCRIPTOR = "go.issue12403.Parsable";
            
            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) {
                case Proxy.CALL_FromJSON: {
                    String param_jstr;
                    param_jstr = in.readString();
                    String result = this.FromJSON(param_jstr);
                    out.writeString(result);
                    return;
                }
                case Proxy.CALL_ToJSON: {
                    try {
                        String result = this.ToJSON();
                        out.writeString(result);
                        out.writeString(null);
                    } catch (Exception e) {
                        String result = null;
                        out.writeString(result);
                        out.writeString(e.getMessage());
                    }
                    return;
                }
                default:
                    throw new RuntimeException("unknown code: "+ code);
                }
            }
        }
        
        static final class Proxy implements Parsable {
            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 String FromJSON(String jstr) {
                go.Seq _in = null;
                go.Seq _out = null;
                _out = new go.Seq();
                String _result;
                _in = new go.Seq();
                _in.writeRef(ref);
                _in.writeString(jstr);
                Seq.send(DESCRIPTOR, CALL_FromJSON, _in, _out);
                _result = _out.readString();
                return _result;
            }
            
            public String ToJSON() throws Exception {
                go.Seq _in = null;
                go.Seq _out = null;
                _out = new go.Seq();
                String _result;
                _in = new go.Seq();
                _in.writeRef(ref);
                Seq.send(DESCRIPTOR, CALL_ToJSON, _in, _out);
                _result = _out.readString();
                String _err = _out.readString();
                if (_err != null && !_err.isEmpty()) {
                    throw new Exception(_err);
                }
                return _result;
            }
            
            static final int CALL_FromJSON = 0x10a;
            static final int CALL_ToJSON = 0x20a;
        }
    }
    
    private static final String DESCRIPTOR = "issue12403";
}
