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

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