// This file was auto-generated by the veyron vdl tool.
// Source: collection_test_interface.vdl

package mounttable

import (
	// The non-user imports are prefixed with "__" to prevent collisions.
	__veyron2 "veyron.io/veyron/veyron2"
	__context "veyron.io/veyron/veyron2/context"
	__ipc "veyron.io/veyron/veyron2/ipc"
	__vdlutil "veyron.io/veyron/veyron2/vdl/vdlutil"
	__wiretype "veyron.io/veyron/veyron2/wiretype"
)

// TODO(toddw): Remove this line once the new signature support is done.
// It corrects a bug where __wiretype is unused in VDL pacakges where only
// bootstrap types are used on interfaces.
const _ = __wiretype.TypeIDInvalid

// CollectionClientMethods is the client interface
// containing Collection methods.
type CollectionClientMethods interface {
	// Export sets the value for a name.  Overwrite controls the behavior when
	// an entry exists, if Overwrite is true, then the binding is replaced,
	// otherwise the call fails with an error.  The Val must be no larger than
	// MaxSize bytes.
	Export(ctx __context.T, Val string, Overwrite bool, opts ...__ipc.CallOpt) error
	// Lookup retrieves the value associated with a name.  Returns an error if
	// there is no such binding.
	Lookup(__context.T, ...__ipc.CallOpt) ([]byte, error)
}

// CollectionClientStub adds universal methods to CollectionClientMethods.
type CollectionClientStub interface {
	CollectionClientMethods
	__ipc.UniversalServiceMethods
}

// CollectionClient returns a client stub for Collection.
func CollectionClient(name string, opts ...__ipc.BindOpt) CollectionClientStub {
	var client __ipc.Client
	for _, opt := range opts {
		if clientOpt, ok := opt.(__ipc.Client); ok {
			client = clientOpt
		}
	}
	return implCollectionClientStub{name, client}
}

type implCollectionClientStub struct {
	name   string
	client __ipc.Client
}

func (c implCollectionClientStub) c(ctx __context.T) __ipc.Client {
	if c.client != nil {
		return c.client
	}
	return __veyron2.RuntimeFromContext(ctx).Client()
}

func (c implCollectionClientStub) Export(ctx __context.T, i0 string, i1 bool, opts ...__ipc.CallOpt) (err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Export", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&err); ierr != nil {
		err = ierr
	}
	return
}

func (c implCollectionClientStub) Lookup(ctx __context.T, opts ...__ipc.CallOpt) (o0 []byte, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Lookup", nil, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

func (c implCollectionClientStub) Signature(ctx __context.T, opts ...__ipc.CallOpt) (o0 __ipc.ServiceSignature, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Signature", nil, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

// CollectionServerMethods is the interface a server writer
// implements for Collection.
type CollectionServerMethods interface {
	// Export sets the value for a name.  Overwrite controls the behavior when
	// an entry exists, if Overwrite is true, then the binding is replaced,
	// otherwise the call fails with an error.  The Val must be no larger than
	// MaxSize bytes.
	Export(ctx __ipc.ServerContext, Val string, Overwrite bool) error
	// Lookup retrieves the value associated with a name.  Returns an error if
	// there is no such binding.
	Lookup(__ipc.ServerContext) ([]byte, error)
}

// CollectionServerStubMethods is the server interface containing
// Collection methods, as expected by ipc.Server.
// There is no difference between this interface and CollectionServerMethods
// since there are no streaming methods.
type CollectionServerStubMethods CollectionServerMethods

// CollectionServerStub adds universal methods to CollectionServerStubMethods.
type CollectionServerStub interface {
	CollectionServerStubMethods
	// Describe the Collection interfaces.
	Describe__() []__ipc.InterfaceDesc
	// Signature will be replaced with Describe__.
	Signature(ctx __ipc.ServerContext) (__ipc.ServiceSignature, error)
}

// CollectionServer returns a server stub for Collection.
// It converts an implementation of CollectionServerMethods into
// an object that may be used by ipc.Server.
func CollectionServer(impl CollectionServerMethods) CollectionServerStub {
	stub := implCollectionServerStub{
		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 := __ipc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := __ipc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implCollectionServerStub struct {
	impl CollectionServerMethods
	gs   *__ipc.GlobState
}

func (s implCollectionServerStub) Export(ctx __ipc.ServerContext, i0 string, i1 bool) error {
	return s.impl.Export(ctx, i0, i1)
}

func (s implCollectionServerStub) Lookup(ctx __ipc.ServerContext) ([]byte, error) {
	return s.impl.Lookup(ctx)
}

func (s implCollectionServerStub) Globber() *__ipc.GlobState {
	return s.gs
}

func (s implCollectionServerStub) Describe__() []__ipc.InterfaceDesc {
	return []__ipc.InterfaceDesc{CollectionDesc}
}

// CollectionDesc describes the Collection interface.
var CollectionDesc __ipc.InterfaceDesc = descCollection

// descCollection hides the desc to keep godoc clean.
var descCollection = __ipc.InterfaceDesc{
	Name:    "Collection",
	PkgPath: "veyron.io/veyron/veyron/services/mounttable/lib",
	Methods: []__ipc.MethodDesc{
		{
			Name: "Export",
			Doc:  "// Export sets the value for a name.  Overwrite controls the behavior when\n// an entry exists, if Overwrite is true, then the binding is replaced,\n// otherwise the call fails with an error.  The Val must be no larger than\n// MaxSize bytes.",
			InArgs: []__ipc.ArgDesc{
				{"Val", ``},       // string
				{"Overwrite", ``}, // bool
			},
			OutArgs: []__ipc.ArgDesc{
				{"", ``}, // error
			},
		},
		{
			Name: "Lookup",
			Doc:  "// Lookup retrieves the value associated with a name.  Returns an error if\n// there is no such binding.",
			OutArgs: []__ipc.ArgDesc{
				{"", ``}, // []byte
				{"", ``}, // error
			},
		},
	},
}

func (s implCollectionServerStub) Signature(ctx __ipc.ServerContext) (__ipc.ServiceSignature, error) {
	// TODO(toddw): Replace with new Describe__ implementation.
	result := __ipc.ServiceSignature{Methods: make(map[string]__ipc.MethodSignature)}
	result.Methods["Export"] = __ipc.MethodSignature{
		InArgs: []__ipc.MethodArgument{
			{Name: "Val", Type: 3},
			{Name: "Overwrite", Type: 2},
		},
		OutArgs: []__ipc.MethodArgument{
			{Name: "", Type: 65},
		},
	}
	result.Methods["Lookup"] = __ipc.MethodSignature{
		InArgs: []__ipc.MethodArgument{},
		OutArgs: []__ipc.MethodArgument{
			{Name: "", Type: 67},
			{Name: "", Type: 65},
		},
	}

	result.TypeDefs = []__vdlutil.Any{
		__wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, __wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, __wiretype.SliceType{Elem: 0x42, Name: "", Tags: []string(nil)}}

	return result, nil
}
