// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by the vanadium vdl tool.
// Package: tunnel

// Package tunnel defines an interface for creating a network tunnel from client
// to server.
package tunnel

import (
	"fmt"
	"io"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/vdl"
)

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

//////////////////////////////////////////////////
// Type definitions

type WindowSize struct {
	Rows uint16
	Cols uint16
}

func (WindowSize) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/tunnel.WindowSize"`
}) {
}

func (x WindowSize) VDLIsZero() bool {
	return x == WindowSize{}
}

func (x WindowSize) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.Rows != 0 {
		if err := enc.NextFieldValueUint("Rows", vdl.Uint16Type, uint64(x.Rows)); err != nil {
			return err
		}
	}
	if x.Cols != 0 {
		if err := enc.NextFieldValueUint("Cols", vdl.Uint16Type, uint64(x.Cols)); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *WindowSize) VDLRead(dec vdl.Decoder) error {
	*x = WindowSize{}
	if err := dec.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Rows":
			switch value, err := dec.ReadValueUint(16); {
			case err != nil:
				return err
			default:
				x.Rows = uint16(value)
			}
		case "Cols":
			switch value, err := dec.ReadValueUint(16); {
			case err != nil:
				return err
			default:
				x.Cols = uint16(value)
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type ShellOpts struct {
	UsePty      bool       // Whether to open a pseudo-terminal.
	Environment []string   // Environment variables to pass to the remote shell.
	WinSize     WindowSize // The size of the window.
}

func (ShellOpts) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/tunnel.ShellOpts"`
}) {
}

func (x ShellOpts) VDLIsZero() bool {
	if x.UsePty {
		return false
	}
	if len(x.Environment) != 0 {
		return false
	}
	if x.WinSize != (WindowSize{}) {
		return false
	}
	return true
}

func (x ShellOpts) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	if x.UsePty {
		if err := enc.NextFieldValueBool("UsePty", vdl.BoolType, x.UsePty); err != nil {
			return err
		}
	}
	if len(x.Environment) != 0 {
		if err := enc.NextField("Environment"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Environment); err != nil {
			return err
		}
	}
	if x.WinSize != (WindowSize{}) {
		if err := enc.NextField("WinSize"); err != nil {
			return err
		}
		if err := x.WinSize.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []string) error {
	if err := enc.StartValue(__VDLType_list_3); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ShellOpts) VDLRead(dec vdl.Decoder) error {
	*x = ShellOpts{}
	if err := dec.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "UsePty":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.UsePty = value
			}
		case "Environment":
			if err := __VDLReadAnon_list_1(dec, &x.Environment); err != nil {
				return err
			}
		case "WinSize":
			if err := x.WinSize.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]string) error {
	if err := dec.StartValue(__VDLType_list_3); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]string, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, elem, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			*x = append(*x, elem)
		}
	}
}

// TODO(toddw): Replace Unused with the unnamed empty struct{}.
type Unused struct {
}

func (Unused) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/examples/tunnel.Unused"`
}) {
}

func (x Unused) VDLIsZero() bool {
	return x == Unused{}
}

func (x Unused) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Unused) VDLRead(dec vdl.Decoder) error {
	*x = Unused{}
	if err := dec.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type (
	// ClientShellPacket represents any single field of the ClientShellPacket union type.
	ClientShellPacket interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the ClientShellPacket union type.
		__VDLReflect(__ClientShellPacketReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// ClientShellPacketStdin represents field Stdin of the ClientShellPacket union type.
	//
	// Bytes going to the shell's stdin.
	ClientShellPacketStdin struct{ Value []byte }
	// ClientShellPacketEndOfFile represents field EndOfFile of the ClientShellPacket union type.
	//
	// Indicates that stdin should be closed. The presence of this field indicates
	// EOF. Its actual value is ignored.
	ClientShellPacketEndOfFile struct{ Value Unused }
	// ClientShellPacketWinSize represents field WinSize of the ClientShellPacket union type.
	//
	// A dynamic update of the window size.
	ClientShellPacketWinSize struct{ Value WindowSize }
	// __ClientShellPacketReflect describes the ClientShellPacket union type.
	__ClientShellPacketReflect struct {
		Name  string `vdl:"v.io/x/ref/examples/tunnel.ClientShellPacket"`
		Type  ClientShellPacket
		Union struct {
			Stdin     ClientShellPacketStdin
			EndOfFile ClientShellPacketEndOfFile
			WinSize   ClientShellPacketWinSize
		}
	}
)

func (x ClientShellPacketStdin) Index() int                              { return 0 }
func (x ClientShellPacketStdin) Interface() interface{}                  { return x.Value }
func (x ClientShellPacketStdin) Name() string                            { return "Stdin" }
func (x ClientShellPacketStdin) __VDLReflect(__ClientShellPacketReflect) {}

func (x ClientShellPacketEndOfFile) Index() int                              { return 1 }
func (x ClientShellPacketEndOfFile) Interface() interface{}                  { return x.Value }
func (x ClientShellPacketEndOfFile) Name() string                            { return "EndOfFile" }
func (x ClientShellPacketEndOfFile) __VDLReflect(__ClientShellPacketReflect) {}

func (x ClientShellPacketWinSize) Index() int                              { return 2 }
func (x ClientShellPacketWinSize) Interface() interface{}                  { return x.Value }
func (x ClientShellPacketWinSize) Name() string                            { return "WinSize" }
func (x ClientShellPacketWinSize) __VDLReflect(__ClientShellPacketReflect) {}

func (x ClientShellPacketStdin) VDLIsZero() bool {
	return len(x.Value) == 0
}

func (x ClientShellPacketEndOfFile) VDLIsZero() bool {
	return false
}

func (x ClientShellPacketWinSize) VDLIsZero() bool {
	return false
}

func (x ClientShellPacketStdin) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_6); err != nil {
		return err
	}
	if err := enc.NextFieldValueBytes("Stdin", __VDLType_list_5, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x ClientShellPacketEndOfFile) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_6); err != nil {
		return err
	}
	if err := enc.NextField("EndOfFile"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x ClientShellPacketWinSize) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_6); err != nil {
		return err
	}
	if err := enc.NextField("WinSize"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadClientShellPacket(dec vdl.Decoder, x *ClientShellPacket) error {
	if err := dec.StartValue(__VDLType_union_6); err != nil {
		return err
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "Stdin":
		var field ClientShellPacketStdin
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	case "EndOfFile":
		var field ClientShellPacketEndOfFile
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "WinSize":
		var field ClientShellPacketWinSize
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "":
		return fmt.Errorf("missing field in union %T, from %v", x, dec.Type())
	default:
		return fmt.Errorf("field %q not in union %T, from %v", f, x, dec.Type())
	}
	switch f, err := dec.NextField(); {
	case err != nil:
		return err
	case f != "":
		return fmt.Errorf("extra field %q in union %T, from %v", f, x, dec.Type())
	}
	return dec.FinishValue()
}

type (
	// ServerShellPacket represents any single field of the ServerShellPacket union type.
	ServerShellPacket interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the ServerShellPacket union type.
		__VDLReflect(__ServerShellPacketReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// ServerShellPacketStdout represents field Stdout of the ServerShellPacket union type.
	//
	// Bytes coming from the shell's stdout.
	ServerShellPacketStdout struct{ Value []byte }
	// ServerShellPacketStderr represents field Stderr of the ServerShellPacket union type.
	//
	// Bytes coming from the shell's stderr.
	ServerShellPacketStderr struct{ Value []byte }
	// __ServerShellPacketReflect describes the ServerShellPacket union type.
	__ServerShellPacketReflect struct {
		Name  string `vdl:"v.io/x/ref/examples/tunnel.ServerShellPacket"`
		Type  ServerShellPacket
		Union struct {
			Stdout ServerShellPacketStdout
			Stderr ServerShellPacketStderr
		}
	}
)

func (x ServerShellPacketStdout) Index() int                              { return 0 }
func (x ServerShellPacketStdout) Interface() interface{}                  { return x.Value }
func (x ServerShellPacketStdout) Name() string                            { return "Stdout" }
func (x ServerShellPacketStdout) __VDLReflect(__ServerShellPacketReflect) {}

func (x ServerShellPacketStderr) Index() int                              { return 1 }
func (x ServerShellPacketStderr) Interface() interface{}                  { return x.Value }
func (x ServerShellPacketStderr) Name() string                            { return "Stderr" }
func (x ServerShellPacketStderr) __VDLReflect(__ServerShellPacketReflect) {}

func (x ServerShellPacketStdout) VDLIsZero() bool {
	return len(x.Value) == 0
}

func (x ServerShellPacketStderr) VDLIsZero() bool {
	return false
}

func (x ServerShellPacketStdout) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_7); err != nil {
		return err
	}
	if err := enc.NextFieldValueBytes("Stdout", __VDLType_list_5, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x ServerShellPacketStderr) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_7); err != nil {
		return err
	}
	if err := enc.NextFieldValueBytes("Stderr", __VDLType_list_5, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadServerShellPacket(dec vdl.Decoder, x *ServerShellPacket) error {
	if err := dec.StartValue(__VDLType_union_7); err != nil {
		return err
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "Stdout":
		var field ServerShellPacketStdout
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	case "Stderr":
		var field ServerShellPacketStderr
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	case "":
		return fmt.Errorf("missing field in union %T, from %v", x, dec.Type())
	default:
		return fmt.Errorf("field %q not in union %T, from %v", f, x, dec.Type())
	}
	switch f, err := dec.NextField(); {
	case err != nil:
		return err
	case f != "":
		return fmt.Errorf("extra field %q in union %T, from %v", f, x, dec.Type())
	}
	return dec.FinishValue()
}

//////////////////////////////////////////////////
// Interface definitions

// TunnelClientMethods is the client interface
// containing Tunnel methods.
type TunnelClientMethods interface {
	// The Forward method is used for network forwarding. All the data sent over
	// the byte stream is forwarded to the requested network address and all the
	// data received from that network connection is sent back on the reply
	// stream.
	Forward(_ *context.T, network string, address string, _ ...rpc.CallOpt) (TunnelForwardClientCall, error)
	// The ReverseForward method is used for network forwarding from the server
	// back to the client. The server process listens on the requested network
	// address, forwarding all connections by calling Forwarder.Forward on the
	// caller.
	ReverseForward(_ *context.T, network string, address string, _ ...rpc.CallOpt) error
	// The Shell method is used to either run shell commands remotely, or to open
	// an interactive shell. The data received over the byte stream is sent to the
	// shell's stdin, and the data received from the shell's stdout and stderr is
	// sent back in the reply stream. It returns the exit status of the shell
	// command as an integer exit code and a human readable string.
	Shell(_ *context.T, command string, shellOpts ShellOpts, _ ...rpc.CallOpt) (TunnelShellClientCall, error)
}

// TunnelClientStub adds universal methods to TunnelClientMethods.
type TunnelClientStub interface {
	TunnelClientMethods
	rpc.UniversalServiceMethods
}

// TunnelClient returns a client stub for Tunnel.
func TunnelClient(name string) TunnelClientStub {
	return implTunnelClientStub{name}
}

type implTunnelClientStub struct {
	name string
}

func (c implTunnelClientStub) Forward(ctx *context.T, i0 string, i1 string, opts ...rpc.CallOpt) (ocall TunnelForwardClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Forward", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implTunnelForwardClientCall{ClientCall: call}
	return
}

func (c implTunnelClientStub) ReverseForward(ctx *context.T, i0 string, i1 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ReverseForward", []interface{}{i0, i1}, nil, opts...)
	return
}

func (c implTunnelClientStub) Shell(ctx *context.T, i0 string, i1 ShellOpts, opts ...rpc.CallOpt) (ocall TunnelShellClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Shell", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implTunnelShellClientCall{ClientCall: call}
	return
}

// TunnelForwardClientStream is the client stream for Tunnel.Forward.
type TunnelForwardClientStream interface {
	// RecvStream returns the receiver side of the Tunnel.Forward client stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Tunnel.Forward client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item []byte) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	}
}

// TunnelForwardClientCall represents the call returned from Tunnel.Forward.
type TunnelForwardClientCall interface {
	TunnelForwardClientStream
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() error
}

type implTunnelForwardClientCall struct {
	rpc.ClientCall
	valRecv []byte
	errRecv error
}

func (c *implTunnelForwardClientCall) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implTunnelForwardClientCallRecv{c}
}

type implTunnelForwardClientCallRecv struct {
	c *implTunnelForwardClientCall
}

func (c implTunnelForwardClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implTunnelForwardClientCallRecv) Value() []byte {
	return c.c.valRecv
}
func (c implTunnelForwardClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implTunnelForwardClientCall) SendStream() interface {
	Send(item []byte) error
	Close() error
} {
	return implTunnelForwardClientCallSend{c}
}

type implTunnelForwardClientCallSend struct {
	c *implTunnelForwardClientCall
}

func (c implTunnelForwardClientCallSend) Send(item []byte) error {
	return c.c.Send(item)
}
func (c implTunnelForwardClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implTunnelForwardClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// TunnelShellClientStream is the client stream for Tunnel.Shell.
type TunnelShellClientStream interface {
	// RecvStream returns the receiver side of the Tunnel.Shell client stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() ServerShellPacket
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Tunnel.Shell client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item ClientShellPacket) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	}
}

// TunnelShellClientCall represents the call returned from Tunnel.Shell.
type TunnelShellClientCall interface {
	TunnelShellClientStream
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() (exitCode int32, exitMsg string, _ error)
}

type implTunnelShellClientCall struct {
	rpc.ClientCall
	valRecv ServerShellPacket
	errRecv error
}

func (c *implTunnelShellClientCall) RecvStream() interface {
	Advance() bool
	Value() ServerShellPacket
	Err() error
} {
	return implTunnelShellClientCallRecv{c}
}

type implTunnelShellClientCallRecv struct {
	c *implTunnelShellClientCall
}

func (c implTunnelShellClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implTunnelShellClientCallRecv) Value() ServerShellPacket {
	return c.c.valRecv
}
func (c implTunnelShellClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implTunnelShellClientCall) SendStream() interface {
	Send(item ClientShellPacket) error
	Close() error
} {
	return implTunnelShellClientCallSend{c}
}

type implTunnelShellClientCallSend struct {
	c *implTunnelShellClientCall
}

func (c implTunnelShellClientCallSend) Send(item ClientShellPacket) error {
	return c.c.Send(item)
}
func (c implTunnelShellClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implTunnelShellClientCall) Finish() (o0 int32, o1 string, err error) {
	err = c.ClientCall.Finish(&o0, &o1)
	return
}

// TunnelServerMethods is the interface a server writer
// implements for Tunnel.
type TunnelServerMethods interface {
	// The Forward method is used for network forwarding. All the data sent over
	// the byte stream is forwarded to the requested network address and all the
	// data received from that network connection is sent back on the reply
	// stream.
	Forward(_ *context.T, _ TunnelForwardServerCall, network string, address string) error
	// The ReverseForward method is used for network forwarding from the server
	// back to the client. The server process listens on the requested network
	// address, forwarding all connections by calling Forwarder.Forward on the
	// caller.
	ReverseForward(_ *context.T, _ rpc.ServerCall, network string, address string) error
	// The Shell method is used to either run shell commands remotely, or to open
	// an interactive shell. The data received over the byte stream is sent to the
	// shell's stdin, and the data received from the shell's stdout and stderr is
	// sent back in the reply stream. It returns the exit status of the shell
	// command as an integer exit code and a human readable string.
	Shell(_ *context.T, _ TunnelShellServerCall, command string, shellOpts ShellOpts) (exitCode int32, exitMsg string, _ error)
}

// TunnelServerStubMethods is the server interface containing
// Tunnel methods, as expected by rpc.Server.
// The only difference between this interface and TunnelServerMethods
// is the streaming methods.
type TunnelServerStubMethods interface {
	// The Forward method is used for network forwarding. All the data sent over
	// the byte stream is forwarded to the requested network address and all the
	// data received from that network connection is sent back on the reply
	// stream.
	Forward(_ *context.T, _ *TunnelForwardServerCallStub, network string, address string) error
	// The ReverseForward method is used for network forwarding from the server
	// back to the client. The server process listens on the requested network
	// address, forwarding all connections by calling Forwarder.Forward on the
	// caller.
	ReverseForward(_ *context.T, _ rpc.ServerCall, network string, address string) error
	// The Shell method is used to either run shell commands remotely, or to open
	// an interactive shell. The data received over the byte stream is sent to the
	// shell's stdin, and the data received from the shell's stdout and stderr is
	// sent back in the reply stream. It returns the exit status of the shell
	// command as an integer exit code and a human readable string.
	Shell(_ *context.T, _ *TunnelShellServerCallStub, command string, shellOpts ShellOpts) (exitCode int32, exitMsg string, _ error)
}

// TunnelServerStub adds universal methods to TunnelServerStubMethods.
type TunnelServerStub interface {
	TunnelServerStubMethods
	// Describe the Tunnel interfaces.
	Describe__() []rpc.InterfaceDesc
}

// TunnelServer returns a server stub for Tunnel.
// It converts an implementation of TunnelServerMethods into
// an object that may be used by rpc.Server.
func TunnelServer(impl TunnelServerMethods) TunnelServerStub {
	stub := implTunnelServerStub{
		impl: impl,
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implTunnelServerStub struct {
	impl TunnelServerMethods
	gs   *rpc.GlobState
}

func (s implTunnelServerStub) Forward(ctx *context.T, call *TunnelForwardServerCallStub, i0 string, i1 string) error {
	return s.impl.Forward(ctx, call, i0, i1)
}

func (s implTunnelServerStub) ReverseForward(ctx *context.T, call rpc.ServerCall, i0 string, i1 string) error {
	return s.impl.ReverseForward(ctx, call, i0, i1)
}

func (s implTunnelServerStub) Shell(ctx *context.T, call *TunnelShellServerCallStub, i0 string, i1 ShellOpts) (int32, string, error) {
	return s.impl.Shell(ctx, call, i0, i1)
}

func (s implTunnelServerStub) Globber() *rpc.GlobState {
	return s.gs
}

func (s implTunnelServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{TunnelDesc}
}

// TunnelDesc describes the Tunnel interface.
var TunnelDesc rpc.InterfaceDesc = descTunnel

// descTunnel hides the desc to keep godoc clean.
var descTunnel = rpc.InterfaceDesc{
	Name:    "Tunnel",
	PkgPath: "v.io/x/ref/examples/tunnel",
	Methods: []rpc.MethodDesc{
		{
			Name: "Forward",
			Doc:  "// The Forward method is used for network forwarding. All the data sent over\n// the byte stream is forwarded to the requested network address and all the\n// data received from that network connection is sent back on the reply\n// stream.",
			InArgs: []rpc.ArgDesc{
				{"network", ``}, // string
				{"address", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "ReverseForward",
			Doc:  "// The ReverseForward method is used for network forwarding from the server\n// back to the client. The server process listens on the requested network\n// address, forwarding all connections by calling Forwarder.Forward on the\n// caller.",
			InArgs: []rpc.ArgDesc{
				{"network", ``}, // string
				{"address", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "Shell",
			Doc:  "// The Shell method is used to either run shell commands remotely, or to open\n// an interactive shell. The data received over the byte stream is sent to the\n// shell's stdin, and the data received from the shell's stdout and stderr is\n// sent back in the reply stream. It returns the exit status of the shell\n// command as an integer exit code and a human readable string.",
			InArgs: []rpc.ArgDesc{
				{"command", ``},   // string
				{"shellOpts", ``}, // ShellOpts
			},
			OutArgs: []rpc.ArgDesc{
				{"exitCode", ``}, // int32
				{"exitMsg", ``},  // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
	},
}

// TunnelForwardServerStream is the server stream for Tunnel.Forward.
type TunnelForwardServerStream interface {
	// RecvStream returns the receiver side of the Tunnel.Forward server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Tunnel.Forward server stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors encountered
		// while sending.  Blocks if there is no buffer space; will unblock when
		// buffer space is available.
		Send(item []byte) error
	}
}

// TunnelForwardServerCall represents the context passed to Tunnel.Forward.
type TunnelForwardServerCall interface {
	rpc.ServerCall
	TunnelForwardServerStream
}

// TunnelForwardServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements TunnelForwardServerCall.
type TunnelForwardServerCallStub struct {
	rpc.StreamServerCall
	valRecv []byte
	errRecv error
}

// Init initializes TunnelForwardServerCallStub from rpc.StreamServerCall.
func (s *TunnelForwardServerCallStub) Init(call rpc.StreamServerCall) {
	s.StreamServerCall = call
}

// RecvStream returns the receiver side of the Tunnel.Forward server stream.
func (s *TunnelForwardServerCallStub) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implTunnelForwardServerCallRecv{s}
}

type implTunnelForwardServerCallRecv struct {
	s *TunnelForwardServerCallStub
}

func (s implTunnelForwardServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implTunnelForwardServerCallRecv) Value() []byte {
	return s.s.valRecv
}
func (s implTunnelForwardServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}

// SendStream returns the send side of the Tunnel.Forward server stream.
func (s *TunnelForwardServerCallStub) SendStream() interface {
	Send(item []byte) error
} {
	return implTunnelForwardServerCallSend{s}
}

type implTunnelForwardServerCallSend struct {
	s *TunnelForwardServerCallStub
}

func (s implTunnelForwardServerCallSend) Send(item []byte) error {
	return s.s.Send(item)
}

// TunnelShellServerStream is the server stream for Tunnel.Shell.
type TunnelShellServerStream interface {
	// RecvStream returns the receiver side of the Tunnel.Shell server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() ClientShellPacket
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Tunnel.Shell server stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors encountered
		// while sending.  Blocks if there is no buffer space; will unblock when
		// buffer space is available.
		Send(item ServerShellPacket) error
	}
}

// TunnelShellServerCall represents the context passed to Tunnel.Shell.
type TunnelShellServerCall interface {
	rpc.ServerCall
	TunnelShellServerStream
}

// TunnelShellServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements TunnelShellServerCall.
type TunnelShellServerCallStub struct {
	rpc.StreamServerCall
	valRecv ClientShellPacket
	errRecv error
}

// Init initializes TunnelShellServerCallStub from rpc.StreamServerCall.
func (s *TunnelShellServerCallStub) Init(call rpc.StreamServerCall) {
	s.StreamServerCall = call
}

// RecvStream returns the receiver side of the Tunnel.Shell server stream.
func (s *TunnelShellServerCallStub) RecvStream() interface {
	Advance() bool
	Value() ClientShellPacket
	Err() error
} {
	return implTunnelShellServerCallRecv{s}
}

type implTunnelShellServerCallRecv struct {
	s *TunnelShellServerCallStub
}

func (s implTunnelShellServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implTunnelShellServerCallRecv) Value() ClientShellPacket {
	return s.s.valRecv
}
func (s implTunnelShellServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}

// SendStream returns the send side of the Tunnel.Shell server stream.
func (s *TunnelShellServerCallStub) SendStream() interface {
	Send(item ServerShellPacket) error
} {
	return implTunnelShellServerCallSend{s}
}

type implTunnelShellServerCallSend struct {
	s *TunnelShellServerCallStub
}

func (s implTunnelShellServerCallSend) Send(item ServerShellPacket) error {
	return s.s.Send(item)
}

// ForwarderClientMethods is the client interface
// containing Forwarder methods.
type ForwarderClientMethods interface {
	// The Forward method is used for network forwarding. All the data sent over
	// the byte stream is forwarded to a predetermined network address and all the
	// data received from that network connection is sent back on the reply
	// stream.
	Forward(*context.T, ...rpc.CallOpt) (ForwarderForwardClientCall, error)
}

// ForwarderClientStub adds universal methods to ForwarderClientMethods.
type ForwarderClientStub interface {
	ForwarderClientMethods
	rpc.UniversalServiceMethods
}

// ForwarderClient returns a client stub for Forwarder.
func ForwarderClient(name string) ForwarderClientStub {
	return implForwarderClientStub{name}
}

type implForwarderClientStub struct {
	name string
}

func (c implForwarderClientStub) Forward(ctx *context.T, opts ...rpc.CallOpt) (ocall ForwarderForwardClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Forward", nil, opts...); err != nil {
		return
	}
	ocall = &implForwarderForwardClientCall{ClientCall: call}
	return
}

// ForwarderForwardClientStream is the client stream for Forwarder.Forward.
type ForwarderForwardClientStream interface {
	// RecvStream returns the receiver side of the Forwarder.Forward client stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Forwarder.Forward client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item []byte) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	}
}

// ForwarderForwardClientCall represents the call returned from Forwarder.Forward.
type ForwarderForwardClientCall interface {
	ForwarderForwardClientStream
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() error
}

type implForwarderForwardClientCall struct {
	rpc.ClientCall
	valRecv []byte
	errRecv error
}

func (c *implForwarderForwardClientCall) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implForwarderForwardClientCallRecv{c}
}

type implForwarderForwardClientCallRecv struct {
	c *implForwarderForwardClientCall
}

func (c implForwarderForwardClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implForwarderForwardClientCallRecv) Value() []byte {
	return c.c.valRecv
}
func (c implForwarderForwardClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implForwarderForwardClientCall) SendStream() interface {
	Send(item []byte) error
	Close() error
} {
	return implForwarderForwardClientCallSend{c}
}

type implForwarderForwardClientCallSend struct {
	c *implForwarderForwardClientCall
}

func (c implForwarderForwardClientCallSend) Send(item []byte) error {
	return c.c.Send(item)
}
func (c implForwarderForwardClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implForwarderForwardClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// ForwarderServerMethods is the interface a server writer
// implements for Forwarder.
type ForwarderServerMethods interface {
	// The Forward method is used for network forwarding. All the data sent over
	// the byte stream is forwarded to a predetermined network address and all the
	// data received from that network connection is sent back on the reply
	// stream.
	Forward(*context.T, ForwarderForwardServerCall) error
}

// ForwarderServerStubMethods is the server interface containing
// Forwarder methods, as expected by rpc.Server.
// The only difference between this interface and ForwarderServerMethods
// is the streaming methods.
type ForwarderServerStubMethods interface {
	// The Forward method is used for network forwarding. All the data sent over
	// the byte stream is forwarded to a predetermined network address and all the
	// data received from that network connection is sent back on the reply
	// stream.
	Forward(*context.T, *ForwarderForwardServerCallStub) error
}

// ForwarderServerStub adds universal methods to ForwarderServerStubMethods.
type ForwarderServerStub interface {
	ForwarderServerStubMethods
	// Describe the Forwarder interfaces.
	Describe__() []rpc.InterfaceDesc
}

// ForwarderServer returns a server stub for Forwarder.
// It converts an implementation of ForwarderServerMethods into
// an object that may be used by rpc.Server.
func ForwarderServer(impl ForwarderServerMethods) ForwarderServerStub {
	stub := implForwarderServerStub{
		impl: impl,
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implForwarderServerStub struct {
	impl ForwarderServerMethods
	gs   *rpc.GlobState
}

func (s implForwarderServerStub) Forward(ctx *context.T, call *ForwarderForwardServerCallStub) error {
	return s.impl.Forward(ctx, call)
}

func (s implForwarderServerStub) Globber() *rpc.GlobState {
	return s.gs
}

func (s implForwarderServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ForwarderDesc}
}

// ForwarderDesc describes the Forwarder interface.
var ForwarderDesc rpc.InterfaceDesc = descForwarder

// descForwarder hides the desc to keep godoc clean.
var descForwarder = rpc.InterfaceDesc{
	Name:    "Forwarder",
	PkgPath: "v.io/x/ref/examples/tunnel",
	Methods: []rpc.MethodDesc{
		{
			Name: "Forward",
			Doc:  "// The Forward method is used for network forwarding. All the data sent over\n// the byte stream is forwarded to a predetermined network address and all the\n// data received from that network connection is sent back on the reply\n// stream.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
	},
}

// ForwarderForwardServerStream is the server stream for Forwarder.Forward.
type ForwarderForwardServerStream interface {
	// RecvStream returns the receiver side of the Forwarder.Forward server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Forwarder.Forward server stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors encountered
		// while sending.  Blocks if there is no buffer space; will unblock when
		// buffer space is available.
		Send(item []byte) error
	}
}

// ForwarderForwardServerCall represents the context passed to Forwarder.Forward.
type ForwarderForwardServerCall interface {
	rpc.ServerCall
	ForwarderForwardServerStream
}

// ForwarderForwardServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements ForwarderForwardServerCall.
type ForwarderForwardServerCallStub struct {
	rpc.StreamServerCall
	valRecv []byte
	errRecv error
}

// Init initializes ForwarderForwardServerCallStub from rpc.StreamServerCall.
func (s *ForwarderForwardServerCallStub) Init(call rpc.StreamServerCall) {
	s.StreamServerCall = call
}

// RecvStream returns the receiver side of the Forwarder.Forward server stream.
func (s *ForwarderForwardServerCallStub) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implForwarderForwardServerCallRecv{s}
}

type implForwarderForwardServerCallRecv struct {
	s *ForwarderForwardServerCallStub
}

func (s implForwarderForwardServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implForwarderForwardServerCallRecv) Value() []byte {
	return s.s.valRecv
}
func (s implForwarderForwardServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}

// SendStream returns the send side of the Forwarder.Forward server stream.
func (s *ForwarderForwardServerCallStub) SendStream() interface {
	Send(item []byte) error
} {
	return implForwarderForwardServerCallSend{s}
}

type implForwarderForwardServerCallSend struct {
	s *ForwarderForwardServerCallStub
}

func (s implForwarderForwardServerCallSend) Send(item []byte) error {
	return s.s.Send(item)
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1 *vdl.Type
	__VDLType_struct_2 *vdl.Type
	__VDLType_list_3   *vdl.Type
	__VDLType_struct_4 *vdl.Type
	__VDLType_list_5   *vdl.Type
	__VDLType_union_6  *vdl.Type
	__VDLType_union_7  *vdl.Type
)

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true

	// Register types.
	vdl.Register((*WindowSize)(nil))
	vdl.Register((*ShellOpts)(nil))
	vdl.Register((*Unused)(nil))
	vdl.Register((*ClientShellPacket)(nil))
	vdl.Register((*ServerShellPacket)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*WindowSize)(nil)).Elem()
	__VDLType_struct_2 = vdl.TypeOf((*ShellOpts)(nil)).Elem()
	__VDLType_list_3 = vdl.TypeOf((*[]string)(nil))
	__VDLType_struct_4 = vdl.TypeOf((*Unused)(nil)).Elem()
	__VDLType_list_5 = vdl.TypeOf((*[]byte)(nil))
	__VDLType_union_6 = vdl.TypeOf((*ClientShellPacket)(nil))
	__VDLType_union_7 = vdl.TypeOf((*ServerShellPacket)(nil))

	return struct{}{}
}
