// 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(0, vdl.Uint16Type, uint64(x.Rows)); err != nil {
			return err
		}
	}
	if x.Cols != 0 {
		if err := enc.NextFieldValueUint(1, vdl.Uint16Type, uint64(x.Cols)); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); 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
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_1 {
			index = __VDLType_struct_1.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueUint(16); {
			case err != nil:
				return err
			default:
				x.Rows = uint16(value)
			}
		case 1:
			switch value, err := dec.ReadValueUint(16); {
			case err != nil:
				return err
			default:
				x.Cols = uint16(value)
			}
		}
	}
}

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(0, vdl.BoolType, x.UsePty); err != nil {
			return err
		}
	}
	if len(x.Environment) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Environment); err != nil {
			return err
		}
	}
	if x.WinSize != (WindowSize{}) {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := x.WinSize.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); 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
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_2 {
			index = __VDLType_struct_2.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.UsePty = value
			}
		case 1:
			if err := __VDLReadAnon_list_1(dec, &x.Environment); err != nil {
				return err
			}
		case 2:
			if err := x.WinSize.VDLRead(dec); 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(-1); 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
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_4 {
			index = __VDLType_struct_4.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		}
	}
}

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(0, __VDLType_list_5, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); 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(1); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); 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(2); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); 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
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_6 {
		name := decType.Field(index).Name
		index = __VDLType_union_6.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field ClientShellPacketStdin
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	case 1:
		var field ClientShellPacketEndOfFile
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case 2:
		var field ClientShellPacketWinSize
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, 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(0, __VDLType_list_5, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); 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(1, __VDLType_list_5, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); 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
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_7 {
		name := decType.Field(index).Name
		index = __VDLType_union_7.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field ServerShellPacketStdout
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	case 1:
		var field ServerShellPacketStderr
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, 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{}{}
}
