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

// Package arith is a vdl test package with imports.
package arith

import (
	"io"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/vdl"
	"v.io/v23/vom"
	"v.io/x/ref/lib/vdl/testdata/arith/exp"
	"v.io/x/ref/lib/vdl/testdata/base"
)

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

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

// Yes shows that bools may be untyped.
const Yes = true // yes trailing doc
// No shows explicit boolean typing.
const No = false
const Hello = "hello"

// Int32Const shows explicit integer typing.
const Int32Const = int32(123)

// Int64Const shows explicit integer conversion from another type, and referencing
// a constant from another package.
const Int64Const = int64(128)

// FloatConst shows arithmetic expressions may be used.
const FloatConst = float64(2)

// Mask shows bitwise operations.
const Mask = uint64(256)

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

// TrigonometryClientMethods is the client interface
// containing Trigonometry methods.
//
// Trigonometry is an interface that specifies a couple trigonometric functions.
type TrigonometryClientMethods interface {
	Sine(_ *context.T, angle float64, _ ...rpc.CallOpt) (float64, error)
	Cosine(_ *context.T, angle float64, _ ...rpc.CallOpt) (float64, error)
}

// TrigonometryClientStub adds universal methods to TrigonometryClientMethods.
type TrigonometryClientStub interface {
	TrigonometryClientMethods
	rpc.UniversalServiceMethods
}

// TrigonometryClient returns a client stub for Trigonometry.
func TrigonometryClient(name string) TrigonometryClientStub {
	return implTrigonometryClientStub{name}
}

type implTrigonometryClientStub struct {
	name string
}

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

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

// TrigonometryServerMethods is the interface a server writer
// implements for Trigonometry.
//
// Trigonometry is an interface that specifies a couple trigonometric functions.
type TrigonometryServerMethods interface {
	Sine(_ *context.T, _ rpc.ServerCall, angle float64) (float64, error)
	Cosine(_ *context.T, _ rpc.ServerCall, angle float64) (float64, error)
}

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

// TrigonometryServerStub adds universal methods to TrigonometryServerStubMethods.
type TrigonometryServerStub interface {
	TrigonometryServerStubMethods
	// Describe the Trigonometry interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

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

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

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

func (s implTrigonometryServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{TrigonometryDesc}
}

// TrigonometryDesc describes the Trigonometry interface.
var TrigonometryDesc rpc.InterfaceDesc = descTrigonometry

// descTrigonometry hides the desc to keep godoc clean.
var descTrigonometry = rpc.InterfaceDesc{
	Name:    "Trigonometry",
	PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
	Doc:     "// Trigonometry is an interface that specifies a couple trigonometric functions.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Sine",
			InArgs: []rpc.ArgDesc{
				{"angle", ``}, // float64
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // float64
			},
		},
		{
			Name: "Cosine",
			InArgs: []rpc.ArgDesc{
				{"angle", ``}, // float64
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // float64
			},
		},
	},
}

// AdvancedMathClientMethods is the client interface
// containing AdvancedMath methods.
//
// AdvancedMath is an interface for more advanced math than arith.  It embeds
// interfaces defined both in the same file and in an external package; and in
// turn it is embedded by arith.Calculator (which is in the same package but
// different file) to verify that embedding works in all these scenarios.
type AdvancedMathClientMethods interface {
	// Trigonometry is an interface that specifies a couple trigonometric functions.
	TrigonometryClientMethods
	exp.ExpClientMethods
}

// AdvancedMathClientStub adds universal methods to AdvancedMathClientMethods.
type AdvancedMathClientStub interface {
	AdvancedMathClientMethods
	rpc.UniversalServiceMethods
}

// AdvancedMathClient returns a client stub for AdvancedMath.
func AdvancedMathClient(name string) AdvancedMathClientStub {
	return implAdvancedMathClientStub{name, TrigonometryClient(name), exp.ExpClient(name)}
}

type implAdvancedMathClientStub struct {
	name string

	TrigonometryClientStub
	exp.ExpClientStub
}

// AdvancedMathServerMethods is the interface a server writer
// implements for AdvancedMath.
//
// AdvancedMath is an interface for more advanced math than arith.  It embeds
// interfaces defined both in the same file and in an external package; and in
// turn it is embedded by arith.Calculator (which is in the same package but
// different file) to verify that embedding works in all these scenarios.
type AdvancedMathServerMethods interface {
	// Trigonometry is an interface that specifies a couple trigonometric functions.
	TrigonometryServerMethods
	exp.ExpServerMethods
}

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

// AdvancedMathServerStub adds universal methods to AdvancedMathServerStubMethods.
type AdvancedMathServerStub interface {
	AdvancedMathServerStubMethods
	// Describe the AdvancedMath interfaces.
	Describe__() []rpc.InterfaceDesc
}

// AdvancedMathServer returns a server stub for AdvancedMath.
// It converts an implementation of AdvancedMathServerMethods into
// an object that may be used by rpc.Server.
func AdvancedMathServer(impl AdvancedMathServerMethods) AdvancedMathServerStub {
	stub := implAdvancedMathServerStub{
		impl: impl,
		TrigonometryServerStub: TrigonometryServer(impl),
		ExpServerStub:          exp.ExpServer(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 implAdvancedMathServerStub struct {
	impl AdvancedMathServerMethods
	TrigonometryServerStub
	exp.ExpServerStub
	gs *rpc.GlobState
}

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

func (s implAdvancedMathServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{AdvancedMathDesc, TrigonometryDesc, exp.ExpDesc}
}

// AdvancedMathDesc describes the AdvancedMath interface.
var AdvancedMathDesc rpc.InterfaceDesc = descAdvancedMath

// descAdvancedMath hides the desc to keep godoc clean.
var descAdvancedMath = rpc.InterfaceDesc{
	Name:    "AdvancedMath",
	PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
	Doc:     "// AdvancedMath is an interface for more advanced math than arith.  It embeds\n// interfaces defined both in the same file and in an external package; and in\n// turn it is embedded by arith.Calculator (which is in the same package but\n// different file) to verify that embedding works in all these scenarios.",
	Embeds: []rpc.EmbedDesc{
		{"Trigonometry", "v.io/x/ref/lib/vdl/testdata/arith", "// Trigonometry is an interface that specifies a couple trigonometric functions."},
		{"Exp", "v.io/x/ref/lib/vdl/testdata/arith/exp", ``},
	},
}

// ArithClientMethods is the client interface
// containing Arith methods.
//
// Arith is an example of an interface definition for an arithmetic service.
// Things to note:
//   * There must be at least 1 out-arg, and the last out-arg must be error.
type ArithClientMethods interface {
	// Add is a typical method with multiple input and output arguments.
	Add(_ *context.T, a int32, b int32, _ ...rpc.CallOpt) (int32, error)
	// DivMod shows that runs of args with the same type can use the short form,
	// just like Go.
	DivMod(_ *context.T, a int32, b int32, _ ...rpc.CallOpt) (quot int32, rem int32, _ error)
	// Sub shows that you can use data types defined in other packages.
	Sub(_ *context.T, args base.Args, _ ...rpc.CallOpt) (int32, error)
	// Mul tries another data type defined in another package.
	Mul(_ *context.T, nested base.NestedArgs, _ ...rpc.CallOpt) (int32, error)
	// GenError shows that it's fine to have no in args, and no out args other
	// than "error".  In addition GenError shows the usage of tags.  Tags are a
	// sequence of constants.  There's no requirement on uniqueness of types or
	// values, and regular const expressions may also be used.
	GenError(*context.T, ...rpc.CallOpt) error
	// Count shows using only an int32 out-stream type, with no in-stream type.
	Count(_ *context.T, start int32, _ ...rpc.CallOpt) (ArithCountClientCall, error)
	// StreamingAdd shows a bidirectional stream.
	StreamingAdd(*context.T, ...rpc.CallOpt) (ArithStreamingAddClientCall, error)
	// QuoteAny shows the any built-in type, representing a value of any type.
	QuoteAny(_ *context.T, a *vom.RawBytes, _ ...rpc.CallOpt) (*vom.RawBytes, error)
}

// ArithClientStub adds universal methods to ArithClientMethods.
type ArithClientStub interface {
	ArithClientMethods
	rpc.UniversalServiceMethods
}

// ArithClient returns a client stub for Arith.
func ArithClient(name string) ArithClientStub {
	return implArithClientStub{name}
}

type implArithClientStub struct {
	name string
}

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

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

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

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

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

func (c implArithClientStub) Count(ctx *context.T, i0 int32, opts ...rpc.CallOpt) (ocall ArithCountClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Count", []interface{}{i0}, opts...); err != nil {
		return
	}
	ocall = &implArithCountClientCall{ClientCall: call}
	return
}

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

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

// ArithCountClientStream is the client stream for Arith.Count.
type ArithCountClientStream interface {
	// RecvStream returns the receiver side of the Arith.Count 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() int32
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// ArithCountClientCall represents the call returned from Arith.Count.
type ArithCountClientCall interface {
	ArithCountClientStream
	// Finish blocks until the server is done, and returns the positional return
	// values for 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 implArithCountClientCall struct {
	rpc.ClientCall
	valRecv int32
	errRecv error
}

func (c *implArithCountClientCall) RecvStream() interface {
	Advance() bool
	Value() int32
	Err() error
} {
	return implArithCountClientCallRecv{c}
}

type implArithCountClientCallRecv struct {
	c *implArithCountClientCall
}

func (c implArithCountClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implArithCountClientCallRecv) Value() int32 {
	return c.c.valRecv
}
func (c implArithCountClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implArithCountClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// ArithStreamingAddClientStream is the client stream for Arith.StreamingAdd.
type ArithStreamingAddClientStream interface {
	// RecvStream returns the receiver side of the Arith.StreamingAdd 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() int32
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Arith.StreamingAdd 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 int32) 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
	}
}

// ArithStreamingAddClientCall represents the call returned from Arith.StreamingAdd.
type ArithStreamingAddClientCall interface {
	ArithStreamingAddClientStream
	// 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() (total int32, _ error)
}

type implArithStreamingAddClientCall struct {
	rpc.ClientCall
	valRecv int32
	errRecv error
}

func (c *implArithStreamingAddClientCall) RecvStream() interface {
	Advance() bool
	Value() int32
	Err() error
} {
	return implArithStreamingAddClientCallRecv{c}
}

type implArithStreamingAddClientCallRecv struct {
	c *implArithStreamingAddClientCall
}

func (c implArithStreamingAddClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implArithStreamingAddClientCallRecv) Value() int32 {
	return c.c.valRecv
}
func (c implArithStreamingAddClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implArithStreamingAddClientCall) SendStream() interface {
	Send(item int32) error
	Close() error
} {
	return implArithStreamingAddClientCallSend{c}
}

type implArithStreamingAddClientCallSend struct {
	c *implArithStreamingAddClientCall
}

func (c implArithStreamingAddClientCallSend) Send(item int32) error {
	return c.c.Send(item)
}
func (c implArithStreamingAddClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implArithStreamingAddClientCall) Finish() (o0 int32, err error) {
	err = c.ClientCall.Finish(&o0)
	return
}

// ArithServerMethods is the interface a server writer
// implements for Arith.
//
// Arith is an example of an interface definition for an arithmetic service.
// Things to note:
//   * There must be at least 1 out-arg, and the last out-arg must be error.
type ArithServerMethods interface {
	// Add is a typical method with multiple input and output arguments.
	Add(_ *context.T, _ rpc.ServerCall, a int32, b int32) (int32, error)
	// DivMod shows that runs of args with the same type can use the short form,
	// just like Go.
	DivMod(_ *context.T, _ rpc.ServerCall, a int32, b int32) (quot int32, rem int32, _ error)
	// Sub shows that you can use data types defined in other packages.
	Sub(_ *context.T, _ rpc.ServerCall, args base.Args) (int32, error)
	// Mul tries another data type defined in another package.
	Mul(_ *context.T, _ rpc.ServerCall, nested base.NestedArgs) (int32, error)
	// GenError shows that it's fine to have no in args, and no out args other
	// than "error".  In addition GenError shows the usage of tags.  Tags are a
	// sequence of constants.  There's no requirement on uniqueness of types or
	// values, and regular const expressions may also be used.
	GenError(*context.T, rpc.ServerCall) error
	// Count shows using only an int32 out-stream type, with no in-stream type.
	Count(_ *context.T, _ ArithCountServerCall, start int32) error
	// StreamingAdd shows a bidirectional stream.
	StreamingAdd(*context.T, ArithStreamingAddServerCall) (total int32, _ error)
	// QuoteAny shows the any built-in type, representing a value of any type.
	QuoteAny(_ *context.T, _ rpc.ServerCall, a *vom.RawBytes) (*vom.RawBytes, error)
}

// ArithServerStubMethods is the server interface containing
// Arith methods, as expected by rpc.Server.
// The only difference between this interface and ArithServerMethods
// is the streaming methods.
type ArithServerStubMethods interface {
	// Add is a typical method with multiple input and output arguments.
	Add(_ *context.T, _ rpc.ServerCall, a int32, b int32) (int32, error)
	// DivMod shows that runs of args with the same type can use the short form,
	// just like Go.
	DivMod(_ *context.T, _ rpc.ServerCall, a int32, b int32) (quot int32, rem int32, _ error)
	// Sub shows that you can use data types defined in other packages.
	Sub(_ *context.T, _ rpc.ServerCall, args base.Args) (int32, error)
	// Mul tries another data type defined in another package.
	Mul(_ *context.T, _ rpc.ServerCall, nested base.NestedArgs) (int32, error)
	// GenError shows that it's fine to have no in args, and no out args other
	// than "error".  In addition GenError shows the usage of tags.  Tags are a
	// sequence of constants.  There's no requirement on uniqueness of types or
	// values, and regular const expressions may also be used.
	GenError(*context.T, rpc.ServerCall) error
	// Count shows using only an int32 out-stream type, with no in-stream type.
	Count(_ *context.T, _ *ArithCountServerCallStub, start int32) error
	// StreamingAdd shows a bidirectional stream.
	StreamingAdd(*context.T, *ArithStreamingAddServerCallStub) (total int32, _ error)
	// QuoteAny shows the any built-in type, representing a value of any type.
	QuoteAny(_ *context.T, _ rpc.ServerCall, a *vom.RawBytes) (*vom.RawBytes, error)
}

// ArithServerStub adds universal methods to ArithServerStubMethods.
type ArithServerStub interface {
	ArithServerStubMethods
	// Describe the Arith interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implArithServerStub) Add(ctx *context.T, call rpc.ServerCall, i0 int32, i1 int32) (int32, error) {
	return s.impl.Add(ctx, call, i0, i1)
}

func (s implArithServerStub) DivMod(ctx *context.T, call rpc.ServerCall, i0 int32, i1 int32) (int32, int32, error) {
	return s.impl.DivMod(ctx, call, i0, i1)
}

func (s implArithServerStub) Sub(ctx *context.T, call rpc.ServerCall, i0 base.Args) (int32, error) {
	return s.impl.Sub(ctx, call, i0)
}

func (s implArithServerStub) Mul(ctx *context.T, call rpc.ServerCall, i0 base.NestedArgs) (int32, error) {
	return s.impl.Mul(ctx, call, i0)
}

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

func (s implArithServerStub) Count(ctx *context.T, call *ArithCountServerCallStub, i0 int32) error {
	return s.impl.Count(ctx, call, i0)
}

func (s implArithServerStub) StreamingAdd(ctx *context.T, call *ArithStreamingAddServerCallStub) (int32, error) {
	return s.impl.StreamingAdd(ctx, call)
}

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

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

func (s implArithServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ArithDesc}
}

// ArithDesc describes the Arith interface.
var ArithDesc rpc.InterfaceDesc = descArith

// descArith hides the desc to keep godoc clean.
var descArith = rpc.InterfaceDesc{
	Name:    "Arith",
	PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
	Doc:     "// Arith is an example of an interface definition for an arithmetic service.\n// Things to note:\n//   * There must be at least 1 out-arg, and the last out-arg must be error.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Add",
			Doc:  "// Add is a typical method with multiple input and output arguments.",
			InArgs: []rpc.ArgDesc{
				{"a", ``}, // int32
				{"b", ``}, // int32
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int32
			},
		},
		{
			Name: "DivMod",
			Doc:  "// DivMod shows that runs of args with the same type can use the short form,\n// just like Go.",
			InArgs: []rpc.ArgDesc{
				{"a", ``}, // int32
				{"b", ``}, // int32
			},
			OutArgs: []rpc.ArgDesc{
				{"quot", ``}, // int32
				{"rem", ``},  // int32
			},
		},
		{
			Name: "Sub",
			Doc:  "// Sub shows that you can use data types defined in other packages.",
			InArgs: []rpc.ArgDesc{
				{"args", ``}, // base.Args
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int32
			},
		},
		{
			Name: "Mul",
			Doc:  "// Mul tries another data type defined in another package.",
			InArgs: []rpc.ArgDesc{
				{"nested", ``}, // base.NestedArgs
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int32
			},
		},
		{
			Name: "GenError",
			Doc:  "// GenError shows that it's fine to have no in args, and no out args other\n// than \"error\".  In addition GenError shows the usage of tags.  Tags are a\n// sequence of constants.  There's no requirement on uniqueness of types or\n// values, and regular const expressions may also be used.",
			Tags: []*vdl.Value{vdl.ValueOf("foo"), vdl.ValueOf("barz"), vdl.ValueOf("hello"), vdl.ValueOf(int32(129)), vdl.ValueOf(uint64(36))},
		},
		{
			Name: "Count",
			Doc:  "// Count shows using only an int32 out-stream type, with no in-stream type.",
			InArgs: []rpc.ArgDesc{
				{"start", ``}, // int32
			},
		},
		{
			Name: "StreamingAdd",
			Doc:  "// StreamingAdd shows a bidirectional stream.",
			OutArgs: []rpc.ArgDesc{
				{"total", ``}, // int32
			},
		},
		{
			Name: "QuoteAny",
			Doc:  "// QuoteAny shows the any built-in type, representing a value of any type.",
			InArgs: []rpc.ArgDesc{
				{"a", ``}, // *vom.RawBytes
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // *vom.RawBytes
			},
		},
	},
}

// ArithCountServerStream is the server stream for Arith.Count.
type ArithCountServerStream interface {
	// SendStream returns the send side of the Arith.Count 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 int32) error
	}
}

// ArithCountServerCall represents the context passed to Arith.Count.
type ArithCountServerCall interface {
	rpc.ServerCall
	ArithCountServerStream
}

// ArithCountServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements ArithCountServerCall.
type ArithCountServerCallStub struct {
	rpc.StreamServerCall
}

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

// SendStream returns the send side of the Arith.Count server stream.
func (s *ArithCountServerCallStub) SendStream() interface {
	Send(item int32) error
} {
	return implArithCountServerCallSend{s}
}

type implArithCountServerCallSend struct {
	s *ArithCountServerCallStub
}

func (s implArithCountServerCallSend) Send(item int32) error {
	return s.s.Send(item)
}

// ArithStreamingAddServerStream is the server stream for Arith.StreamingAdd.
type ArithStreamingAddServerStream interface {
	// RecvStream returns the receiver side of the Arith.StreamingAdd 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() int32
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Arith.StreamingAdd 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 int32) error
	}
}

// ArithStreamingAddServerCall represents the context passed to Arith.StreamingAdd.
type ArithStreamingAddServerCall interface {
	rpc.ServerCall
	ArithStreamingAddServerStream
}

// ArithStreamingAddServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements ArithStreamingAddServerCall.
type ArithStreamingAddServerCallStub struct {
	rpc.StreamServerCall
	valRecv int32
	errRecv error
}

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

// RecvStream returns the receiver side of the Arith.StreamingAdd server stream.
func (s *ArithStreamingAddServerCallStub) RecvStream() interface {
	Advance() bool
	Value() int32
	Err() error
} {
	return implArithStreamingAddServerCallRecv{s}
}

type implArithStreamingAddServerCallRecv struct {
	s *ArithStreamingAddServerCallStub
}

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

// SendStream returns the send side of the Arith.StreamingAdd server stream.
func (s *ArithStreamingAddServerCallStub) SendStream() interface {
	Send(item int32) error
} {
	return implArithStreamingAddServerCallSend{s}
}

type implArithStreamingAddServerCallSend struct {
	s *ArithStreamingAddServerCallStub
}

func (s implArithStreamingAddServerCallSend) Send(item int32) error {
	return s.s.Send(item)
}

// CalculatorClientMethods is the client interface
// containing Calculator methods.
type CalculatorClientMethods interface {
	// Arith is an example of an interface definition for an arithmetic service.
	// Things to note:
	//   * There must be at least 1 out-arg, and the last out-arg must be error.
	ArithClientMethods
	// AdvancedMath is an interface for more advanced math than arith.  It embeds
	// interfaces defined both in the same file and in an external package; and in
	// turn it is embedded by arith.Calculator (which is in the same package but
	// different file) to verify that embedding works in all these scenarios.
	AdvancedMathClientMethods
	On(*context.T, ...rpc.CallOpt) error  // On turns the calculator on.
	Off(*context.T, ...rpc.CallOpt) error // Off turns the calculator off.
}

// CalculatorClientStub adds universal methods to CalculatorClientMethods.
type CalculatorClientStub interface {
	CalculatorClientMethods
	rpc.UniversalServiceMethods
}

// CalculatorClient returns a client stub for Calculator.
func CalculatorClient(name string) CalculatorClientStub {
	return implCalculatorClientStub{name, ArithClient(name), AdvancedMathClient(name)}
}

type implCalculatorClientStub struct {
	name string

	ArithClientStub
	AdvancedMathClientStub
}

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

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

// CalculatorServerMethods is the interface a server writer
// implements for Calculator.
type CalculatorServerMethods interface {
	// Arith is an example of an interface definition for an arithmetic service.
	// Things to note:
	//   * There must be at least 1 out-arg, and the last out-arg must be error.
	ArithServerMethods
	// AdvancedMath is an interface for more advanced math than arith.  It embeds
	// interfaces defined both in the same file and in an external package; and in
	// turn it is embedded by arith.Calculator (which is in the same package but
	// different file) to verify that embedding works in all these scenarios.
	AdvancedMathServerMethods
	On(*context.T, rpc.ServerCall) error  // On turns the calculator on.
	Off(*context.T, rpc.ServerCall) error // Off turns the calculator off.
}

// CalculatorServerStubMethods is the server interface containing
// Calculator methods, as expected by rpc.Server.
// The only difference between this interface and CalculatorServerMethods
// is the streaming methods.
type CalculatorServerStubMethods interface {
	// Arith is an example of an interface definition for an arithmetic service.
	// Things to note:
	//   * There must be at least 1 out-arg, and the last out-arg must be error.
	ArithServerStubMethods
	// AdvancedMath is an interface for more advanced math than arith.  It embeds
	// interfaces defined both in the same file and in an external package; and in
	// turn it is embedded by arith.Calculator (which is in the same package but
	// different file) to verify that embedding works in all these scenarios.
	AdvancedMathServerStubMethods
	On(*context.T, rpc.ServerCall) error  // On turns the calculator on.
	Off(*context.T, rpc.ServerCall) error // Off turns the calculator off.
}

// CalculatorServerStub adds universal methods to CalculatorServerStubMethods.
type CalculatorServerStub interface {
	CalculatorServerStubMethods
	// Describe the Calculator interfaces.
	Describe__() []rpc.InterfaceDesc
}

// CalculatorServer returns a server stub for Calculator.
// It converts an implementation of CalculatorServerMethods into
// an object that may be used by rpc.Server.
func CalculatorServer(impl CalculatorServerMethods) CalculatorServerStub {
	stub := implCalculatorServerStub{
		impl:                   impl,
		ArithServerStub:        ArithServer(impl),
		AdvancedMathServerStub: AdvancedMathServer(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 implCalculatorServerStub struct {
	impl CalculatorServerMethods
	ArithServerStub
	AdvancedMathServerStub
	gs *rpc.GlobState
}

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

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

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

func (s implCalculatorServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{CalculatorDesc, ArithDesc, AdvancedMathDesc, TrigonometryDesc, exp.ExpDesc}
}

// CalculatorDesc describes the Calculator interface.
var CalculatorDesc rpc.InterfaceDesc = descCalculator

// descCalculator hides the desc to keep godoc clean.
var descCalculator = rpc.InterfaceDesc{
	Name:    "Calculator",
	PkgPath: "v.io/x/ref/lib/vdl/testdata/arith",
	Embeds: []rpc.EmbedDesc{
		{"Arith", "v.io/x/ref/lib/vdl/testdata/arith", "// Arith is an example of an interface definition for an arithmetic service.\n// Things to note:\n//   * There must be at least 1 out-arg, and the last out-arg must be error."},
		{"AdvancedMath", "v.io/x/ref/lib/vdl/testdata/arith", "// AdvancedMath is an interface for more advanced math than arith.  It embeds\n// interfaces defined both in the same file and in an external package; and in\n// turn it is embedded by arith.Calculator (which is in the same package but\n// different file) to verify that embedding works in all these scenarios."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "On",
		},
		{
			Name: "Off",
			Tags: []*vdl.Value{vdl.ValueOf("offtag")},
		},
	},
}

var __VDLInitCalled bool

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

	return struct{}{}
}
