// 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: test_service

package test_service

import (
	"fmt"
	"io"
	"reflect"
	"time"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/uniqueid"
	"v.io/v23/vdl"
	_ "v.io/v23/vdlroot/time"
	"v.io/v23/vom"
)

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

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

// KeyPageResult is a page of 10 keys.
type KeyPageResult [10]string

func (KeyPageResult) __VDLReflect(struct {
	Name string `vdl:"v.io/x/js.core/test_service.KeyPageResult"`
}) {
}

func (m *KeyPageResult) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	listTarget1, err := t.StartList(tt, 10)
	if err != nil {
		return err
	}
	for i, elem3 := range *m {
		elemTarget2, err := listTarget1.StartElem(i)
		if err != nil {
			return err
		}
		if err := elemTarget2.FromString(string(elem3), tt.NonOptional().Elem()); err != nil {
			return err
		}
		if err := listTarget1.FinishElem(elemTarget2); err != nil {
			return err
		}
	}
	if err := t.FinishList(listTarget1); err != nil {
		return err
	}
	return nil
}

func (m *KeyPageResult) MakeVDLTarget() vdl.Target {
	return &KeyPageResultTarget{Value: m}
}

// KeyPageResult
type KeyPageResultTarget struct {
	Value      *KeyPageResult
	elemTarget vdl.StringTarget
	vdl.TargetBase
	vdl.ListTargetBase
}

func (t *KeyPageResultTarget) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {

	if ttWant := vdl.TypeOf((*KeyPageResult)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *KeyPageResultTarget) StartElem(index int) (elem vdl.Target, _ error) {
	t.elemTarget.Value = &(*t.Value)[index]
	target, err := &t.elemTarget, error(nil)
	return target, err
}
func (t *KeyPageResultTarget) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *KeyPageResultTarget) FinishList(elem vdl.ListTarget) error {

	return nil
}

// KeyValuePair is a representation of a cached key and value pair.
type KeyValuePair struct {
	Key   string
	Value *vom.RawBytes
}

func (KeyValuePair) __VDLReflect(struct {
	Name string `vdl:"v.io/x/js.core/test_service.KeyValuePair"`
}) {
}

func (m *KeyValuePair) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Key")
	if err != vdl.ErrFieldNoExist && err != nil {
		return err
	}
	if err != vdl.ErrFieldNoExist {
		if err := fieldTarget3.FromString(string(m.Key), tt.NonOptional().Field(0).Type); err != nil {
			return err
		}
		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
			return err
		}
	}
	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("Value")
	if err != vdl.ErrFieldNoExist && err != nil {
		return err
	}
	if err != vdl.ErrFieldNoExist {

		if m.Value == nil {
			if err := fieldTarget5.FromNil(tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
		} else {
			if err := m.Value.FillVDLTarget(fieldTarget5, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
		}
		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
			return err
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *KeyValuePair) MakeVDLTarget() vdl.Target {
	return &KeyValuePairTarget{Value: m}
}

type KeyValuePairTarget struct {
	Value     *KeyValuePair
	keyTarget vdl.StringTarget

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *KeyValuePairTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*KeyValuePair)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *KeyValuePairTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Key":
		t.keyTarget.Value = &t.Value.Key
		target, err := &t.keyTarget, error(nil)
		return nil, target, err
	case "Value":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Value))
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/js.core/test_service.KeyValuePair", name)
	}
}
func (t *KeyValuePairTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *KeyValuePairTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

type TestCaveatData struct {
	A string
	B *vom.RawBytes // Use any for value so that we can confirm VDL is being used properly.
}

func (TestCaveatData) __VDLReflect(struct {
	Name string `vdl:"v.io/x/js.core/test_service.TestCaveatData"`
}) {
}

func (m *TestCaveatData) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("A")
	if err != vdl.ErrFieldNoExist && err != nil {
		return err
	}
	if err != vdl.ErrFieldNoExist {
		if err := fieldTarget3.FromString(string(m.A), tt.NonOptional().Field(0).Type); err != nil {
			return err
		}
		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
			return err
		}
	}
	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("B")
	if err != vdl.ErrFieldNoExist && err != nil {
		return err
	}
	if err != vdl.ErrFieldNoExist {

		if m.B == nil {
			if err := fieldTarget5.FromNil(tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
		} else {
			if err := m.B.FillVDLTarget(fieldTarget5, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
		}
		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
			return err
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *TestCaveatData) MakeVDLTarget() vdl.Target {
	return &TestCaveatDataTarget{Value: m}
}

type TestCaveatDataTarget struct {
	Value   *TestCaveatData
	aTarget vdl.StringTarget

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *TestCaveatDataTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*TestCaveatData)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *TestCaveatDataTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "A":
		t.aTarget.Value = &t.Value.A
		target, err := &t.aTarget, error(nil)
		return nil, target, err
	case "B":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.B))
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/js.core/test_service.TestCaveatData", name)
	}
}
func (t *TestCaveatDataTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *TestCaveatDataTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// Create zero values for each type.
var (
	__VDLZeroKeyPageResult  = KeyPageResult{}
	__VDLZeroKeyValuePair   = KeyValuePair{}
	__VDLZeroTestCaveatData = TestCaveatData{}
)

//////////////////////////////////////////////////
// Const definitions

var ConditionallyValidatingTestCaveat = security.CaveatDescriptor{
	Id: uniqueid.Id{
		0,
		17,
		34,
		51,
		68,
		85,
		102,
		119,
		136,
		153,
		170,
		187,
		204,
		221,
		238,
		255,
	},
	ParamType: vdl.TypeOf((*TestCaveatData)(nil)).Elem(),
}

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

// CacheClientMethods is the client interface
// containing Cache methods.
//
// A Cache service mimics the memcache interface.
type CacheClientMethods interface {
	// Set sets a value for a key.
	Set(_ *context.T, key string, value *vom.RawBytes, _ ...rpc.CallOpt) error
	// Get returns the value for a key.  If the value is not found, returns
	// a not found error.
	Get(_ *context.T, key string, _ ...rpc.CallOpt) (*vom.RawBytes, error)
	// Same as Get, but casts the return argument to an byte.
	GetAsByte(_ *context.T, key string, _ ...rpc.CallOpt) (byte, error)
	// Same as Get, but casts the return argument to an int32.
	GetAsInt32(_ *context.T, key string, _ ...rpc.CallOpt) (int32, error)
	// Same as Get, but casts the return argument to an int64.
	GetAsInt64(_ *context.T, key string, _ ...rpc.CallOpt) (int64, error)
	// Same as Get, but casts the return argument to an uint32.
	GetAsUint32(_ *context.T, key string, _ ...rpc.CallOpt) (uint32, error)
	// Same as Get, but casts the return argument to an uint64.
	GetAsUint64(_ *context.T, key string, _ ...rpc.CallOpt) (uint64, error)
	// Same as Get, but casts the return argument to an float32.
	GetAsFloat32(_ *context.T, key string, _ ...rpc.CallOpt) (float32, error)
	// Same as Get, but casts the return argument to an float64.
	GetAsFloat64(_ *context.T, key string, _ ...rpc.CallOpt) (float64, error)
	// Same as Get, but casts the return argument to a string.
	GetAsString(_ *context.T, key string, _ ...rpc.CallOpt) (string, error)
	// Same as Get, but casts the return argument to a bool.
	GetAsBool(_ *context.T, key string, _ ...rpc.CallOpt) (bool, error)
	// Same as Get, but casts the return argument to an error.
	GetAsError(_ *context.T, key string, _ ...rpc.CallOpt) (error, error)
	// AsMap returns the full contents of the cache as a map.
	AsMap(*context.T, ...rpc.CallOpt) (map[string]*vom.RawBytes, error)
	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
	KeyValuePairs(*context.T, ...rpc.CallOpt) ([]KeyValuePair, error)
	// MostRecentSet returns the key and value and the timestamp for the most
	// recent set operation
	// TODO(bprosnitz) support type types and change time to native time type
	MostRecentSet(*context.T, ...rpc.CallOpt) (value KeyValuePair, time int64, _ error)
	// KeyPage indexes into the keys (in alphanumerically sorted order) and
	// returns the indexth page of 10 keys.
	KeyPage(_ *context.T, index int64, _ ...rpc.CallOpt) (KeyPageResult, error)
	// Size returns the total number of entries in the cache.
	Size(*context.T, ...rpc.CallOpt) (int64, error)
	// MultiGet sets up a stream that allows fetching multiple keys.
	MultiGet(*context.T, ...rpc.CallOpt) (CacheMultiGetClientCall, error)
}

// CacheClientStub adds universal methods to CacheClientMethods.
type CacheClientStub interface {
	CacheClientMethods
	rpc.UniversalServiceMethods
}

// CacheClient returns a client stub for Cache.
func CacheClient(name string) CacheClientStub {
	return implCacheClientStub{name}
}

type implCacheClientStub struct {
	name string
}

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

func (c implCacheClientStub) Get(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 *vom.RawBytes, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Get", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsByte(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 byte, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsByte", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsInt32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 int32, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsInt32", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsInt64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 int64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsInt64", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsUint32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 uint32, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsUint32", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsUint64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 uint64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsUint64", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsFloat32(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 float32, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsFloat32", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsFloat64(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 float64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsFloat64", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsString(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsString", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsBool(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 bool, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsBool", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) GetAsError(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 error, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAsError", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) AsMap(ctx *context.T, opts ...rpc.CallOpt) (o0 map[string]*vom.RawBytes, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "AsMap", nil, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) KeyValuePairs(ctx *context.T, opts ...rpc.CallOpt) (o0 []KeyValuePair, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "KeyValuePairs", nil, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) MostRecentSet(ctx *context.T, opts ...rpc.CallOpt) (o0 KeyValuePair, o1 int64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "MostRecentSet", nil, []interface{}{&o0, &o1}, opts...)
	return
}

func (c implCacheClientStub) KeyPage(ctx *context.T, i0 int64, opts ...rpc.CallOpt) (o0 KeyPageResult, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "KeyPage", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implCacheClientStub) Size(ctx *context.T, opts ...rpc.CallOpt) (o0 int64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Size", nil, []interface{}{&o0}, opts...)
	return
}

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

// CacheMultiGetClientStream is the client stream for Cache.MultiGet.
type CacheMultiGetClientStream interface {
	// RecvStream returns the receiver side of the Cache.MultiGet 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() *vom.RawBytes
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Cache.MultiGet 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 string) 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
	}
}

// CacheMultiGetClientCall represents the call returned from Cache.MultiGet.
type CacheMultiGetClientCall interface {
	CacheMultiGetClientStream
	// 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 implCacheMultiGetClientCall struct {
	rpc.ClientCall
	valRecv *vom.RawBytes
	errRecv error
}

func (c *implCacheMultiGetClientCall) RecvStream() interface {
	Advance() bool
	Value() *vom.RawBytes
	Err() error
} {
	return implCacheMultiGetClientCallRecv{c}
}

type implCacheMultiGetClientCallRecv struct {
	c *implCacheMultiGetClientCall
}

func (c implCacheMultiGetClientCallRecv) Advance() bool {
	c.c.valRecv = nil
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implCacheMultiGetClientCallRecv) Value() *vom.RawBytes {
	return c.c.valRecv
}
func (c implCacheMultiGetClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implCacheMultiGetClientCall) SendStream() interface {
	Send(item string) error
	Close() error
} {
	return implCacheMultiGetClientCallSend{c}
}

type implCacheMultiGetClientCallSend struct {
	c *implCacheMultiGetClientCall
}

func (c implCacheMultiGetClientCallSend) Send(item string) error {
	return c.c.Send(item)
}
func (c implCacheMultiGetClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implCacheMultiGetClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// CacheServerMethods is the interface a server writer
// implements for Cache.
//
// A Cache service mimics the memcache interface.
type CacheServerMethods interface {
	// Set sets a value for a key.
	Set(_ *context.T, _ rpc.ServerCall, key string, value *vom.RawBytes) error
	// Get returns the value for a key.  If the value is not found, returns
	// a not found error.
	Get(_ *context.T, _ rpc.ServerCall, key string) (*vom.RawBytes, error)
	// Same as Get, but casts the return argument to an byte.
	GetAsByte(_ *context.T, _ rpc.ServerCall, key string) (byte, error)
	// Same as Get, but casts the return argument to an int32.
	GetAsInt32(_ *context.T, _ rpc.ServerCall, key string) (int32, error)
	// Same as Get, but casts the return argument to an int64.
	GetAsInt64(_ *context.T, _ rpc.ServerCall, key string) (int64, error)
	// Same as Get, but casts the return argument to an uint32.
	GetAsUint32(_ *context.T, _ rpc.ServerCall, key string) (uint32, error)
	// Same as Get, but casts the return argument to an uint64.
	GetAsUint64(_ *context.T, _ rpc.ServerCall, key string) (uint64, error)
	// Same as Get, but casts the return argument to an float32.
	GetAsFloat32(_ *context.T, _ rpc.ServerCall, key string) (float32, error)
	// Same as Get, but casts the return argument to an float64.
	GetAsFloat64(_ *context.T, _ rpc.ServerCall, key string) (float64, error)
	// Same as Get, but casts the return argument to a string.
	GetAsString(_ *context.T, _ rpc.ServerCall, key string) (string, error)
	// Same as Get, but casts the return argument to a bool.
	GetAsBool(_ *context.T, _ rpc.ServerCall, key string) (bool, error)
	// Same as Get, but casts the return argument to an error.
	GetAsError(_ *context.T, _ rpc.ServerCall, key string) (error, error)
	// AsMap returns the full contents of the cache as a map.
	AsMap(*context.T, rpc.ServerCall) (map[string]*vom.RawBytes, error)
	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
	KeyValuePairs(*context.T, rpc.ServerCall) ([]KeyValuePair, error)
	// MostRecentSet returns the key and value and the timestamp for the most
	// recent set operation
	// TODO(bprosnitz) support type types and change time to native time type
	MostRecentSet(*context.T, rpc.ServerCall) (value KeyValuePair, time int64, _ error)
	// KeyPage indexes into the keys (in alphanumerically sorted order) and
	// returns the indexth page of 10 keys.
	KeyPage(_ *context.T, _ rpc.ServerCall, index int64) (KeyPageResult, error)
	// Size returns the total number of entries in the cache.
	Size(*context.T, rpc.ServerCall) (int64, error)
	// MultiGet sets up a stream that allows fetching multiple keys.
	MultiGet(*context.T, CacheMultiGetServerCall) error
}

// CacheServerStubMethods is the server interface containing
// Cache methods, as expected by rpc.Server.
// The only difference between this interface and CacheServerMethods
// is the streaming methods.
type CacheServerStubMethods interface {
	// Set sets a value for a key.
	Set(_ *context.T, _ rpc.ServerCall, key string, value *vom.RawBytes) error
	// Get returns the value for a key.  If the value is not found, returns
	// a not found error.
	Get(_ *context.T, _ rpc.ServerCall, key string) (*vom.RawBytes, error)
	// Same as Get, but casts the return argument to an byte.
	GetAsByte(_ *context.T, _ rpc.ServerCall, key string) (byte, error)
	// Same as Get, but casts the return argument to an int32.
	GetAsInt32(_ *context.T, _ rpc.ServerCall, key string) (int32, error)
	// Same as Get, but casts the return argument to an int64.
	GetAsInt64(_ *context.T, _ rpc.ServerCall, key string) (int64, error)
	// Same as Get, but casts the return argument to an uint32.
	GetAsUint32(_ *context.T, _ rpc.ServerCall, key string) (uint32, error)
	// Same as Get, but casts the return argument to an uint64.
	GetAsUint64(_ *context.T, _ rpc.ServerCall, key string) (uint64, error)
	// Same as Get, but casts the return argument to an float32.
	GetAsFloat32(_ *context.T, _ rpc.ServerCall, key string) (float32, error)
	// Same as Get, but casts the return argument to an float64.
	GetAsFloat64(_ *context.T, _ rpc.ServerCall, key string) (float64, error)
	// Same as Get, but casts the return argument to a string.
	GetAsString(_ *context.T, _ rpc.ServerCall, key string) (string, error)
	// Same as Get, but casts the return argument to a bool.
	GetAsBool(_ *context.T, _ rpc.ServerCall, key string) (bool, error)
	// Same as Get, but casts the return argument to an error.
	GetAsError(_ *context.T, _ rpc.ServerCall, key string) (error, error)
	// AsMap returns the full contents of the cache as a map.
	AsMap(*context.T, rpc.ServerCall) (map[string]*vom.RawBytes, error)
	// KeyValuePairs returns the full contents of the cache as a slice of pairs.
	KeyValuePairs(*context.T, rpc.ServerCall) ([]KeyValuePair, error)
	// MostRecentSet returns the key and value and the timestamp for the most
	// recent set operation
	// TODO(bprosnitz) support type types and change time to native time type
	MostRecentSet(*context.T, rpc.ServerCall) (value KeyValuePair, time int64, _ error)
	// KeyPage indexes into the keys (in alphanumerically sorted order) and
	// returns the indexth page of 10 keys.
	KeyPage(_ *context.T, _ rpc.ServerCall, index int64) (KeyPageResult, error)
	// Size returns the total number of entries in the cache.
	Size(*context.T, rpc.ServerCall) (int64, error)
	// MultiGet sets up a stream that allows fetching multiple keys.
	MultiGet(*context.T, *CacheMultiGetServerCallStub) error
}

// CacheServerStub adds universal methods to CacheServerStubMethods.
type CacheServerStub interface {
	CacheServerStubMethods
	// Describe the Cache interfaces.
	Describe__() []rpc.InterfaceDesc
}

// CacheServer returns a server stub for Cache.
// It converts an implementation of CacheServerMethods into
// an object that may be used by rpc.Server.
func CacheServer(impl CacheServerMethods) CacheServerStub {
	stub := implCacheServerStub{
		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 implCacheServerStub struct {
	impl CacheServerMethods
	gs   *rpc.GlobState
}

func (s implCacheServerStub) Set(ctx *context.T, call rpc.ServerCall, i0 string, i1 *vom.RawBytes) error {
	return s.impl.Set(ctx, call, i0, i1)
}

func (s implCacheServerStub) Get(ctx *context.T, call rpc.ServerCall, i0 string) (*vom.RawBytes, error) {
	return s.impl.Get(ctx, call, i0)
}

func (s implCacheServerStub) GetAsByte(ctx *context.T, call rpc.ServerCall, i0 string) (byte, error) {
	return s.impl.GetAsByte(ctx, call, i0)
}

func (s implCacheServerStub) GetAsInt32(ctx *context.T, call rpc.ServerCall, i0 string) (int32, error) {
	return s.impl.GetAsInt32(ctx, call, i0)
}

func (s implCacheServerStub) GetAsInt64(ctx *context.T, call rpc.ServerCall, i0 string) (int64, error) {
	return s.impl.GetAsInt64(ctx, call, i0)
}

func (s implCacheServerStub) GetAsUint32(ctx *context.T, call rpc.ServerCall, i0 string) (uint32, error) {
	return s.impl.GetAsUint32(ctx, call, i0)
}

func (s implCacheServerStub) GetAsUint64(ctx *context.T, call rpc.ServerCall, i0 string) (uint64, error) {
	return s.impl.GetAsUint64(ctx, call, i0)
}

func (s implCacheServerStub) GetAsFloat32(ctx *context.T, call rpc.ServerCall, i0 string) (float32, error) {
	return s.impl.GetAsFloat32(ctx, call, i0)
}

func (s implCacheServerStub) GetAsFloat64(ctx *context.T, call rpc.ServerCall, i0 string) (float64, error) {
	return s.impl.GetAsFloat64(ctx, call, i0)
}

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

func (s implCacheServerStub) GetAsBool(ctx *context.T, call rpc.ServerCall, i0 string) (bool, error) {
	return s.impl.GetAsBool(ctx, call, i0)
}

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

func (s implCacheServerStub) AsMap(ctx *context.T, call rpc.ServerCall) (map[string]*vom.RawBytes, error) {
	return s.impl.AsMap(ctx, call)
}

func (s implCacheServerStub) KeyValuePairs(ctx *context.T, call rpc.ServerCall) ([]KeyValuePair, error) {
	return s.impl.KeyValuePairs(ctx, call)
}

func (s implCacheServerStub) MostRecentSet(ctx *context.T, call rpc.ServerCall) (KeyValuePair, int64, error) {
	return s.impl.MostRecentSet(ctx, call)
}

func (s implCacheServerStub) KeyPage(ctx *context.T, call rpc.ServerCall, i0 int64) (KeyPageResult, error) {
	return s.impl.KeyPage(ctx, call, i0)
}

func (s implCacheServerStub) Size(ctx *context.T, call rpc.ServerCall) (int64, error) {
	return s.impl.Size(ctx, call)
}

func (s implCacheServerStub) MultiGet(ctx *context.T, call *CacheMultiGetServerCallStub) error {
	return s.impl.MultiGet(ctx, call)
}

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

func (s implCacheServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{CacheDesc}
}

// CacheDesc describes the Cache interface.
var CacheDesc rpc.InterfaceDesc = descCache

// descCache hides the desc to keep godoc clean.
var descCache = rpc.InterfaceDesc{
	Name:    "Cache",
	PkgPath: "v.io/x/js.core/test_service",
	Doc:     "// A Cache service mimics the memcache interface.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Set",
			Doc:  "// Set sets a value for a key.",
			InArgs: []rpc.ArgDesc{
				{"key", ``},   // string
				{"value", ``}, // *vom.RawBytes
			},
		},
		{
			Name: "Get",
			Doc:  "// Get returns the value for a key.  If the value is not found, returns\n// a not found error.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // *vom.RawBytes
			},
		},
		{
			Name: "GetAsByte",
			Doc:  "// Same as Get, but casts the return argument to an byte.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // byte
			},
		},
		{
			Name: "GetAsInt32",
			Doc:  "// Same as Get, but casts the return argument to an int32.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int32
			},
		},
		{
			Name: "GetAsInt64",
			Doc:  "// Same as Get, but casts the return argument to an int64.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int64
			},
		},
		{
			Name: "GetAsUint32",
			Doc:  "// Same as Get, but casts the return argument to an uint32.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // uint32
			},
		},
		{
			Name: "GetAsUint64",
			Doc:  "// Same as Get, but casts the return argument to an uint64.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // uint64
			},
		},
		{
			Name: "GetAsFloat32",
			Doc:  "// Same as Get, but casts the return argument to an float32.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // float32
			},
		},
		{
			Name: "GetAsFloat64",
			Doc:  "// Same as Get, but casts the return argument to an float64.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // float64
			},
		},
		{
			Name: "GetAsString",
			Doc:  "// Same as Get, but casts the return argument to a string.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
		},
		{
			Name: "GetAsBool",
			Doc:  "// Same as Get, but casts the return argument to a bool.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
		},
		{
			Name: "GetAsError",
			Doc:  "// Same as Get, but casts the return argument to an error.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // error
			},
		},
		{
			Name: "AsMap",
			Doc:  "// AsMap returns the full contents of the cache as a map.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // map[string]*vom.RawBytes
			},
		},
		{
			Name: "KeyValuePairs",
			Doc:  "// KeyValuePairs returns the full contents of the cache as a slice of pairs.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []KeyValuePair
			},
		},
		{
			Name: "MostRecentSet",
			Doc:  "// MostRecentSet returns the key and value and the timestamp for the most\n// recent set operation\n// TODO(bprosnitz) support type types and change time to native time type",
			OutArgs: []rpc.ArgDesc{
				{"value", ``}, // KeyValuePair
				{"time", ``},  // int64
			},
		},
		{
			Name: "KeyPage",
			Doc:  "// KeyPage indexes into the keys (in alphanumerically sorted order) and\n// returns the indexth page of 10 keys.",
			InArgs: []rpc.ArgDesc{
				{"index", ``}, // int64
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // KeyPageResult
			},
		},
		{
			Name: "Size",
			Doc:  "// Size returns the total number of entries in the cache.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int64
			},
		},
		{
			Name: "MultiGet",
			Doc:  "// MultiGet sets up a stream that allows fetching multiple keys.",
		},
	},
}

// CacheMultiGetServerStream is the server stream for Cache.MultiGet.
type CacheMultiGetServerStream interface {
	// RecvStream returns the receiver side of the Cache.MultiGet 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() string
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Cache.MultiGet 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 *vom.RawBytes) error
	}
}

// CacheMultiGetServerCall represents the context passed to Cache.MultiGet.
type CacheMultiGetServerCall interface {
	rpc.ServerCall
	CacheMultiGetServerStream
}

// CacheMultiGetServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements CacheMultiGetServerCall.
type CacheMultiGetServerCallStub struct {
	rpc.StreamServerCall
	valRecv string
	errRecv error
}

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

// RecvStream returns the receiver side of the Cache.MultiGet server stream.
func (s *CacheMultiGetServerCallStub) RecvStream() interface {
	Advance() bool
	Value() string
	Err() error
} {
	return implCacheMultiGetServerCallRecv{s}
}

type implCacheMultiGetServerCallRecv struct {
	s *CacheMultiGetServerCallStub
}

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

// SendStream returns the send side of the Cache.MultiGet server stream.
func (s *CacheMultiGetServerCallStub) SendStream() interface {
	Send(item *vom.RawBytes) error
} {
	return implCacheMultiGetServerCallSend{s}
}

type implCacheMultiGetServerCallSend struct {
	s *CacheMultiGetServerCallStub
}

func (s implCacheMultiGetServerCallSend) Send(item *vom.RawBytes) error {
	return s.s.Send(item)
}

// CancelCollectorClientMethods is the client interface
// containing CancelCollector methods.
//
// CancelCollector is a test interface for use in testing cancellation and deadlines.
type CancelCollectorClientMethods interface {
	// A function that never returns, but records the status of the given key.
	NeverReturn(_ *context.T, key int64, _ ...rpc.CallOpt) error
	// Wait for the call with the given key to have the given status.  Possible statuses are:
	// "running", and, "cancelled".  Returns the number of nanoseconds left on
	// the deadline of the specified call when the call first began.
	WaitForStatus(_ *context.T, key int64, status string, _ ...rpc.CallOpt) (timeout int64, _ error)
}

// CancelCollectorClientStub adds universal methods to CancelCollectorClientMethods.
type CancelCollectorClientStub interface {
	CancelCollectorClientMethods
	rpc.UniversalServiceMethods
}

// CancelCollectorClient returns a client stub for CancelCollector.
func CancelCollectorClient(name string) CancelCollectorClientStub {
	return implCancelCollectorClientStub{name}
}

type implCancelCollectorClientStub struct {
	name string
}

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

func (c implCancelCollectorClientStub) WaitForStatus(ctx *context.T, i0 int64, i1 string, opts ...rpc.CallOpt) (o0 int64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "WaitForStatus", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
	return
}

// CancelCollectorServerMethods is the interface a server writer
// implements for CancelCollector.
//
// CancelCollector is a test interface for use in testing cancellation and deadlines.
type CancelCollectorServerMethods interface {
	// A function that never returns, but records the status of the given key.
	NeverReturn(_ *context.T, _ rpc.ServerCall, key int64) error
	// Wait for the call with the given key to have the given status.  Possible statuses are:
	// "running", and, "cancelled".  Returns the number of nanoseconds left on
	// the deadline of the specified call when the call first began.
	WaitForStatus(_ *context.T, _ rpc.ServerCall, key int64, status string) (timeout int64, _ error)
}

// CancelCollectorServerStubMethods is the server interface containing
// CancelCollector methods, as expected by rpc.Server.
// There is no difference between this interface and CancelCollectorServerMethods
// since there are no streaming methods.
type CancelCollectorServerStubMethods CancelCollectorServerMethods

// CancelCollectorServerStub adds universal methods to CancelCollectorServerStubMethods.
type CancelCollectorServerStub interface {
	CancelCollectorServerStubMethods
	// Describe the CancelCollector interfaces.
	Describe__() []rpc.InterfaceDesc
}

// CancelCollectorServer returns a server stub for CancelCollector.
// It converts an implementation of CancelCollectorServerMethods into
// an object that may be used by rpc.Server.
func CancelCollectorServer(impl CancelCollectorServerMethods) CancelCollectorServerStub {
	stub := implCancelCollectorServerStub{
		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 implCancelCollectorServerStub struct {
	impl CancelCollectorServerMethods
	gs   *rpc.GlobState
}

func (s implCancelCollectorServerStub) NeverReturn(ctx *context.T, call rpc.ServerCall, i0 int64) error {
	return s.impl.NeverReturn(ctx, call, i0)
}

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

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

func (s implCancelCollectorServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{CancelCollectorDesc}
}

// CancelCollectorDesc describes the CancelCollector interface.
var CancelCollectorDesc rpc.InterfaceDesc = descCancelCollector

// descCancelCollector hides the desc to keep godoc clean.
var descCancelCollector = rpc.InterfaceDesc{
	Name:    "CancelCollector",
	PkgPath: "v.io/x/js.core/test_service",
	Doc:     "// CancelCollector is a test interface for use in testing cancellation and deadlines.",
	Methods: []rpc.MethodDesc{
		{
			Name: "NeverReturn",
			Doc:  "// A function that never returns, but records the status of the given key.",
			InArgs: []rpc.ArgDesc{
				{"key", ``}, // int64
			},
		},
		{
			Name: "WaitForStatus",
			Doc:  "// Wait for the call with the given key to have the given status.  Possible statuses are:\n// \"running\", and, \"cancelled\".  Returns the number of nanoseconds left on\n// the deadline of the specified call when the call first began.",
			InArgs: []rpc.ArgDesc{
				{"key", ``},    // int64
				{"status", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"timeout", ``}, // int64
			},
		},
	},
}

// ErrorThrowerClientMethods is the client interface
// containing ErrorThrower methods.
//
// A testing interface with methods that throw various types of errors
type ErrorThrowerClientMethods interface {
	// Throws v23/vError.Aborted error
	ThrowAborted(*context.T, ...rpc.CallOpt) error
	// Throws v23/vError.BadArg error
	ThrowBadArg(*context.T, ...rpc.CallOpt) error
	// Throws v23/vError.BadProtocol error
	ThrowBadProtocol(*context.T, ...rpc.CallOpt) error
	// Throws v23/vError.Internal error
	ThrowInternal(*context.T, ...rpc.CallOpt) error
	// Throws v23/vError.NoAccess error
	ThrowNoAccess(*context.T, ...rpc.CallOpt) error
	// Throws v23/vError.NoExist error
	ThrowNoExist(*context.T, ...rpc.CallOpt) error
	// Throws v23/vError.NoExistOrNoAccess error
	ThrowNoExistOrNoAccess(*context.T, ...rpc.CallOpt) error
	// Throws v23/vError.Unknown error
	ThrowUnknown(*context.T, ...rpc.CallOpt) error
	// Throws normal Go error
	ThrowGoError(*context.T, ...rpc.CallOpt) error
	// Throws custom error created by using Standard
	ThrowCustomStandardError(*context.T, ...rpc.CallOpt) error
}

// ErrorThrowerClientStub adds universal methods to ErrorThrowerClientMethods.
type ErrorThrowerClientStub interface {
	ErrorThrowerClientMethods
	rpc.UniversalServiceMethods
}

// ErrorThrowerClient returns a client stub for ErrorThrower.
func ErrorThrowerClient(name string) ErrorThrowerClientStub {
	return implErrorThrowerClientStub{name}
}

type implErrorThrowerClientStub struct {
	name string
}

func (c implErrorThrowerClientStub) ThrowAborted(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowAborted", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowBadArg(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowBadArg", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowBadProtocol(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowBadProtocol", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowInternal(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowInternal", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowNoAccess(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoAccess", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowNoExist(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoExist", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowNoExistOrNoAccess(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowNoExistOrNoAccess", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowUnknown(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowUnknown", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowGoError(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowGoError", nil, nil, opts...)
	return
}

func (c implErrorThrowerClientStub) ThrowCustomStandardError(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ThrowCustomStandardError", nil, nil, opts...)
	return
}

// ErrorThrowerServerMethods is the interface a server writer
// implements for ErrorThrower.
//
// A testing interface with methods that throw various types of errors
type ErrorThrowerServerMethods interface {
	// Throws v23/vError.Aborted error
	ThrowAborted(*context.T, rpc.ServerCall) error
	// Throws v23/vError.BadArg error
	ThrowBadArg(*context.T, rpc.ServerCall) error
	// Throws v23/vError.BadProtocol error
	ThrowBadProtocol(*context.T, rpc.ServerCall) error
	// Throws v23/vError.Internal error
	ThrowInternal(*context.T, rpc.ServerCall) error
	// Throws v23/vError.NoAccess error
	ThrowNoAccess(*context.T, rpc.ServerCall) error
	// Throws v23/vError.NoExist error
	ThrowNoExist(*context.T, rpc.ServerCall) error
	// Throws v23/vError.NoExistOrNoAccess error
	ThrowNoExistOrNoAccess(*context.T, rpc.ServerCall) error
	// Throws v23/vError.Unknown error
	ThrowUnknown(*context.T, rpc.ServerCall) error
	// Throws normal Go error
	ThrowGoError(*context.T, rpc.ServerCall) error
	// Throws custom error created by using Standard
	ThrowCustomStandardError(*context.T, rpc.ServerCall) error
}

// ErrorThrowerServerStubMethods is the server interface containing
// ErrorThrower methods, as expected by rpc.Server.
// There is no difference between this interface and ErrorThrowerServerMethods
// since there are no streaming methods.
type ErrorThrowerServerStubMethods ErrorThrowerServerMethods

// ErrorThrowerServerStub adds universal methods to ErrorThrowerServerStubMethods.
type ErrorThrowerServerStub interface {
	ErrorThrowerServerStubMethods
	// Describe the ErrorThrower interfaces.
	Describe__() []rpc.InterfaceDesc
}

// ErrorThrowerServer returns a server stub for ErrorThrower.
// It converts an implementation of ErrorThrowerServerMethods into
// an object that may be used by rpc.Server.
func ErrorThrowerServer(impl ErrorThrowerServerMethods) ErrorThrowerServerStub {
	stub := implErrorThrowerServerStub{
		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 implErrorThrowerServerStub struct {
	impl ErrorThrowerServerMethods
	gs   *rpc.GlobState
}

func (s implErrorThrowerServerStub) ThrowAborted(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowAborted(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowBadArg(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowBadArg(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowBadProtocol(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowBadProtocol(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowInternal(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowInternal(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowNoAccess(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowNoAccess(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowNoExist(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowNoExist(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowNoExistOrNoAccess(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowNoExistOrNoAccess(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowUnknown(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowUnknown(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowGoError(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowGoError(ctx, call)
}

func (s implErrorThrowerServerStub) ThrowCustomStandardError(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.ThrowCustomStandardError(ctx, call)
}

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

func (s implErrorThrowerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ErrorThrowerDesc}
}

// ErrorThrowerDesc describes the ErrorThrower interface.
var ErrorThrowerDesc rpc.InterfaceDesc = descErrorThrower

// descErrorThrower hides the desc to keep godoc clean.
var descErrorThrower = rpc.InterfaceDesc{
	Name:    "ErrorThrower",
	PkgPath: "v.io/x/js.core/test_service",
	Doc:     "// A testing interface with methods that throw various types of errors",
	Methods: []rpc.MethodDesc{
		{
			Name: "ThrowAborted",
			Doc:  "// Throws v23/vError.Aborted error",
		},
		{
			Name: "ThrowBadArg",
			Doc:  "// Throws v23/vError.BadArg error",
		},
		{
			Name: "ThrowBadProtocol",
			Doc:  "// Throws v23/vError.BadProtocol error",
		},
		{
			Name: "ThrowInternal",
			Doc:  "// Throws v23/vError.Internal error",
		},
		{
			Name: "ThrowNoAccess",
			Doc:  "// Throws v23/vError.NoAccess error",
		},
		{
			Name: "ThrowNoExist",
			Doc:  "// Throws v23/vError.NoExist error",
		},
		{
			Name: "ThrowNoExistOrNoAccess",
			Doc:  "// Throws v23/vError.NoExistOrNoAccess error",
		},
		{
			Name: "ThrowUnknown",
			Doc:  "// Throws v23/vError.Unknown error",
		},
		{
			Name: "ThrowGoError",
			Doc:  "// Throws normal Go error",
		},
		{
			Name: "ThrowCustomStandardError",
			Doc:  "// Throws custom error created by using Standard",
		},
	},
}

// InvokableTestMethodClientMethods is the client interface
// containing InvokableTestMethod methods.
type InvokableTestMethodClientMethods interface {
	AMethod(*context.T, ...rpc.CallOpt) (string, error)
}

// InvokableTestMethodClientStub adds universal methods to InvokableTestMethodClientMethods.
type InvokableTestMethodClientStub interface {
	InvokableTestMethodClientMethods
	rpc.UniversalServiceMethods
}

// InvokableTestMethodClient returns a client stub for InvokableTestMethod.
func InvokableTestMethodClient(name string) InvokableTestMethodClientStub {
	return implInvokableTestMethodClientStub{name}
}

type implInvokableTestMethodClientStub struct {
	name string
}

func (c implInvokableTestMethodClientStub) AMethod(ctx *context.T, opts ...rpc.CallOpt) (o0 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "AMethod", nil, []interface{}{&o0}, opts...)
	return
}

// InvokableTestMethodServerMethods is the interface a server writer
// implements for InvokableTestMethod.
type InvokableTestMethodServerMethods interface {
	AMethod(*context.T, rpc.ServerCall) (string, error)
}

// InvokableTestMethodServerStubMethods is the server interface containing
// InvokableTestMethod methods, as expected by rpc.Server.
// There is no difference between this interface and InvokableTestMethodServerMethods
// since there are no streaming methods.
type InvokableTestMethodServerStubMethods InvokableTestMethodServerMethods

// InvokableTestMethodServerStub adds universal methods to InvokableTestMethodServerStubMethods.
type InvokableTestMethodServerStub interface {
	InvokableTestMethodServerStubMethods
	// Describe the InvokableTestMethod interfaces.
	Describe__() []rpc.InterfaceDesc
}

// InvokableTestMethodServer returns a server stub for InvokableTestMethod.
// It converts an implementation of InvokableTestMethodServerMethods into
// an object that may be used by rpc.Server.
func InvokableTestMethodServer(impl InvokableTestMethodServerMethods) InvokableTestMethodServerStub {
	stub := implInvokableTestMethodServerStub{
		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 implInvokableTestMethodServerStub struct {
	impl InvokableTestMethodServerMethods
	gs   *rpc.GlobState
}

func (s implInvokableTestMethodServerStub) AMethod(ctx *context.T, call rpc.ServerCall) (string, error) {
	return s.impl.AMethod(ctx, call)
}

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

func (s implInvokableTestMethodServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{InvokableTestMethodDesc}
}

// InvokableTestMethodDesc describes the InvokableTestMethod interface.
var InvokableTestMethodDesc rpc.InterfaceDesc = descInvokableTestMethod

// descInvokableTestMethod hides the desc to keep godoc clean.
var descInvokableTestMethod = rpc.InterfaceDesc{
	Name:    "InvokableTestMethod",
	PkgPath: "v.io/x/js.core/test_service",
	Methods: []rpc.MethodDesc{
		{
			Name: "AMethod",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
		},
	},
}

// InvokeMethodWithCaveatedIdentityClientMethods is the client interface
// containing InvokeMethodWithCaveatedIdentity methods.
type InvokeMethodWithCaveatedIdentityClientMethods interface {
	Invoke(_ *context.T, name string, cavDesc security.CaveatDescriptor, cavParam *vom.RawBytes, _ ...rpc.CallOpt) error
}

// InvokeMethodWithCaveatedIdentityClientStub adds universal methods to InvokeMethodWithCaveatedIdentityClientMethods.
type InvokeMethodWithCaveatedIdentityClientStub interface {
	InvokeMethodWithCaveatedIdentityClientMethods
	rpc.UniversalServiceMethods
}

// InvokeMethodWithCaveatedIdentityClient returns a client stub for InvokeMethodWithCaveatedIdentity.
func InvokeMethodWithCaveatedIdentityClient(name string) InvokeMethodWithCaveatedIdentityClientStub {
	return implInvokeMethodWithCaveatedIdentityClientStub{name}
}

type implInvokeMethodWithCaveatedIdentityClientStub struct {
	name string
}

func (c implInvokeMethodWithCaveatedIdentityClientStub) Invoke(ctx *context.T, i0 string, i1 security.CaveatDescriptor, i2 *vom.RawBytes, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Invoke", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

// InvokeMethodWithCaveatedIdentityServerMethods is the interface a server writer
// implements for InvokeMethodWithCaveatedIdentity.
type InvokeMethodWithCaveatedIdentityServerMethods interface {
	Invoke(_ *context.T, _ rpc.ServerCall, name string, cavDesc security.CaveatDescriptor, cavParam *vom.RawBytes) error
}

// InvokeMethodWithCaveatedIdentityServerStubMethods is the server interface containing
// InvokeMethodWithCaveatedIdentity methods, as expected by rpc.Server.
// There is no difference between this interface and InvokeMethodWithCaveatedIdentityServerMethods
// since there are no streaming methods.
type InvokeMethodWithCaveatedIdentityServerStubMethods InvokeMethodWithCaveatedIdentityServerMethods

// InvokeMethodWithCaveatedIdentityServerStub adds universal methods to InvokeMethodWithCaveatedIdentityServerStubMethods.
type InvokeMethodWithCaveatedIdentityServerStub interface {
	InvokeMethodWithCaveatedIdentityServerStubMethods
	// Describe the InvokeMethodWithCaveatedIdentity interfaces.
	Describe__() []rpc.InterfaceDesc
}

// InvokeMethodWithCaveatedIdentityServer returns a server stub for InvokeMethodWithCaveatedIdentity.
// It converts an implementation of InvokeMethodWithCaveatedIdentityServerMethods into
// an object that may be used by rpc.Server.
func InvokeMethodWithCaveatedIdentityServer(impl InvokeMethodWithCaveatedIdentityServerMethods) InvokeMethodWithCaveatedIdentityServerStub {
	stub := implInvokeMethodWithCaveatedIdentityServerStub{
		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 implInvokeMethodWithCaveatedIdentityServerStub struct {
	impl InvokeMethodWithCaveatedIdentityServerMethods
	gs   *rpc.GlobState
}

func (s implInvokeMethodWithCaveatedIdentityServerStub) Invoke(ctx *context.T, call rpc.ServerCall, i0 string, i1 security.CaveatDescriptor, i2 *vom.RawBytes) error {
	return s.impl.Invoke(ctx, call, i0, i1, i2)
}

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

func (s implInvokeMethodWithCaveatedIdentityServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{InvokeMethodWithCaveatedIdentityDesc}
}

// InvokeMethodWithCaveatedIdentityDesc describes the InvokeMethodWithCaveatedIdentity interface.
var InvokeMethodWithCaveatedIdentityDesc rpc.InterfaceDesc = descInvokeMethodWithCaveatedIdentity

// descInvokeMethodWithCaveatedIdentity hides the desc to keep godoc clean.
var descInvokeMethodWithCaveatedIdentity = rpc.InterfaceDesc{
	Name:    "InvokeMethodWithCaveatedIdentity",
	PkgPath: "v.io/x/js.core/test_service",
	Methods: []rpc.MethodDesc{
		{
			Name: "Invoke",
			InArgs: []rpc.ArgDesc{
				{"name", ``},     // string
				{"cavDesc", ``},  // security.CaveatDescriptor
				{"cavParam", ``}, // *vom.RawBytes
			},
		},
	},
}

// NativeTestClientMethods is the client interface
// containing NativeTest methods.
type NativeTestClientMethods interface {
	PassTime(_ *context.T, t time.Time, _ ...rpc.CallOpt) (time.Time, error)
	PassError(_ *context.T, e error, _ ...rpc.CallOpt) error
}

// NativeTestClientStub adds universal methods to NativeTestClientMethods.
type NativeTestClientStub interface {
	NativeTestClientMethods
	rpc.UniversalServiceMethods
}

// NativeTestClient returns a client stub for NativeTest.
func NativeTestClient(name string) NativeTestClientStub {
	return implNativeTestClientStub{name}
}

type implNativeTestClientStub struct {
	name string
}

func (c implNativeTestClientStub) PassTime(ctx *context.T, i0 time.Time, opts ...rpc.CallOpt) (o0 time.Time, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "PassTime", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

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

// NativeTestServerMethods is the interface a server writer
// implements for NativeTest.
type NativeTestServerMethods interface {
	PassTime(_ *context.T, _ rpc.ServerCall, t time.Time) (time.Time, error)
	PassError(_ *context.T, _ rpc.ServerCall, e error) error
}

// NativeTestServerStubMethods is the server interface containing
// NativeTest methods, as expected by rpc.Server.
// There is no difference between this interface and NativeTestServerMethods
// since there are no streaming methods.
type NativeTestServerStubMethods NativeTestServerMethods

// NativeTestServerStub adds universal methods to NativeTestServerStubMethods.
type NativeTestServerStub interface {
	NativeTestServerStubMethods
	// Describe the NativeTest interfaces.
	Describe__() []rpc.InterfaceDesc
}

// NativeTestServer returns a server stub for NativeTest.
// It converts an implementation of NativeTestServerMethods into
// an object that may be used by rpc.Server.
func NativeTestServer(impl NativeTestServerMethods) NativeTestServerStub {
	stub := implNativeTestServerStub{
		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 implNativeTestServerStub struct {
	impl NativeTestServerMethods
	gs   *rpc.GlobState
}

func (s implNativeTestServerStub) PassTime(ctx *context.T, call rpc.ServerCall, i0 time.Time) (time.Time, error) {
	return s.impl.PassTime(ctx, call, i0)
}

func (s implNativeTestServerStub) PassError(ctx *context.T, call rpc.ServerCall, i0 error) error {
	return s.impl.PassError(ctx, call, i0)
}

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

func (s implNativeTestServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{NativeTestDesc}
}

// NativeTestDesc describes the NativeTest interface.
var NativeTestDesc rpc.InterfaceDesc = descNativeTest

// descNativeTest hides the desc to keep godoc clean.
var descNativeTest = rpc.InterfaceDesc{
	Name:    "NativeTest",
	PkgPath: "v.io/x/js.core/test_service",
	Methods: []rpc.MethodDesc{
		{
			Name: "PassTime",
			InArgs: []rpc.ArgDesc{
				{"t", ``}, // time.Time
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // time.Time
			},
		},
		{
			Name: "PassError",
			InArgs: []rpc.ArgDesc{
				{"e", ``}, // error
			},
		},
	},
}

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{}{}
	}

	// Register types.
	vdl.Register((*KeyPageResult)(nil))
	vdl.Register((*KeyValuePair)(nil))
	vdl.Register((*TestCaveatData)(nil))

	return struct{}{}
}
