// 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.
// Source: service.vdl

// Package nosql defines the wire API for the NoSQL part of Syncbase.
package nosql

import (
	// VDL system imports
	"io"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/vdl"
	"v.io/v23/verror"

	// VDL user imports
	"v.io/v23/security/access"
	"v.io/v23/services/permissions"
	"v.io/v23/services/watch"
)

var (
	ErrBoundToBatch          = verror.Register("v.io/syncbase/v23/services/syncbase/nosql.BoundToBatch", verror.NoRetry, "{1:}{2:} bound to batch")
	ErrNotBoundToBatch       = verror.Register("v.io/syncbase/v23/services/syncbase/nosql.NotBoundToBatch", verror.NoRetry, "{1:}{2:} not bound to batch")
	ErrReadOnlyBatch         = verror.Register("v.io/syncbase/v23/services/syncbase/nosql.ReadOnlyBatch", verror.NoRetry, "{1:}{2:} batch is read-only")
	ErrConcurrentBatch       = verror.Register("v.io/syncbase/v23/services/syncbase/nosql.ConcurrentBatch", verror.NoRetry, "{1:}{2:} concurrent batch")
	ErrSchemaVersionMismatch = verror.Register("v.io/syncbase/v23/services/syncbase/nosql.SchemaVersionMismatch", verror.NoRetry, "{1:}{2:} actual schema version does not match the provided one")
	ErrBlobNotCommitted      = verror.Register("v.io/syncbase/v23/services/syncbase/nosql.BlobNotCommitted", verror.NoRetry, "{1:}{2:} blob is not yet committed")
)

func init() {
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBoundToBatch.ID), "{1:}{2:} bound to batch")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNotBoundToBatch.ID), "{1:}{2:} not bound to batch")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrReadOnlyBatch.ID), "{1:}{2:} batch is read-only")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrConcurrentBatch.ID), "{1:}{2:} concurrent batch")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrSchemaVersionMismatch.ID), "{1:}{2:} actual schema version does not match the provided one")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBlobNotCommitted.ID), "{1:}{2:} blob is not yet committed")
}

// NewErrBoundToBatch returns an error with the ErrBoundToBatch ID.
func NewErrBoundToBatch(ctx *context.T) error {
	return verror.New(ErrBoundToBatch, ctx)
}

// NewErrNotBoundToBatch returns an error with the ErrNotBoundToBatch ID.
func NewErrNotBoundToBatch(ctx *context.T) error {
	return verror.New(ErrNotBoundToBatch, ctx)
}

// NewErrReadOnlyBatch returns an error with the ErrReadOnlyBatch ID.
func NewErrReadOnlyBatch(ctx *context.T) error {
	return verror.New(ErrReadOnlyBatch, ctx)
}

// NewErrConcurrentBatch returns an error with the ErrConcurrentBatch ID.
func NewErrConcurrentBatch(ctx *context.T) error {
	return verror.New(ErrConcurrentBatch, ctx)
}

// NewErrSchemaVersionMismatch returns an error with the ErrSchemaVersionMismatch ID.
func NewErrSchemaVersionMismatch(ctx *context.T) error {
	return verror.New(ErrSchemaVersionMismatch, ctx)
}

// NewErrBlobNotCommitted returns an error with the ErrBlobNotCommitted ID.
func NewErrBlobNotCommitted(ctx *context.T) error {
	return verror.New(ErrBlobNotCommitted, ctx)
}

// DatabaseWatcherClientMethods is the client interface
// containing DatabaseWatcher methods.
//
// DatabaseWatcher allows a client to watch for updates in the database.
// For each watched request, the client will receive a reliable stream of watch
// events without re-ordering. See watch.GlobWatcher for a detailed explanation
// of the behavior.
// TODO(rogulenko): Currently the only supported watch patterns are
// 'table/row*'. Consider changing that.
//
// The watching is done by starting a streaming RPC. The argument to the RPC
// contains the ResumeMarker that points to a particular place in the database
// event log. The result stream consists of a never-ending sequence of Change
// messages (until the call fails or is canceled). Each Change contains the
// Name field in the form "<tableName>/<rowKey>" and the Value field of the
// StoreChange type. If the client has no access to a row specified in a change,
// that change is excluded from the result stream.
//
// The DatabaseWatcher is designed to be used in the following way:
// 1) begin a read-only batch
// 2) read all information your app needs
// 3) read the ResumeMarker
// 4) abort the batch
// 5) start watching changes to the data using the ResumeMarker
// In this configuration the client doesn't miss any changes.
type DatabaseWatcherClientMethods interface {
	// GlobWatcher allows a client to receive updates for changes to objects
	// that match a pattern.  See the package comments for details.
	watch.GlobWatcherClientMethods
	// GetResumeMarker returns the ResumeMarker that points to the current end
	// of the event log. GetResumeMarker() can be called on a batch.
	GetResumeMarker(*context.T, ...rpc.CallOpt) (watch.ResumeMarker, error)
}

// DatabaseWatcherClientStub adds universal methods to DatabaseWatcherClientMethods.
type DatabaseWatcherClientStub interface {
	DatabaseWatcherClientMethods
	rpc.UniversalServiceMethods
}

// DatabaseWatcherClient returns a client stub for DatabaseWatcher.
func DatabaseWatcherClient(name string) DatabaseWatcherClientStub {
	return implDatabaseWatcherClientStub{name, watch.GlobWatcherClient(name)}
}

type implDatabaseWatcherClientStub struct {
	name string

	watch.GlobWatcherClientStub
}

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

// DatabaseWatcherServerMethods is the interface a server writer
// implements for DatabaseWatcher.
//
// DatabaseWatcher allows a client to watch for updates in the database.
// For each watched request, the client will receive a reliable stream of watch
// events without re-ordering. See watch.GlobWatcher for a detailed explanation
// of the behavior.
// TODO(rogulenko): Currently the only supported watch patterns are
// 'table/row*'. Consider changing that.
//
// The watching is done by starting a streaming RPC. The argument to the RPC
// contains the ResumeMarker that points to a particular place in the database
// event log. The result stream consists of a never-ending sequence of Change
// messages (until the call fails or is canceled). Each Change contains the
// Name field in the form "<tableName>/<rowKey>" and the Value field of the
// StoreChange type. If the client has no access to a row specified in a change,
// that change is excluded from the result stream.
//
// The DatabaseWatcher is designed to be used in the following way:
// 1) begin a read-only batch
// 2) read all information your app needs
// 3) read the ResumeMarker
// 4) abort the batch
// 5) start watching changes to the data using the ResumeMarker
// In this configuration the client doesn't miss any changes.
type DatabaseWatcherServerMethods interface {
	// GlobWatcher allows a client to receive updates for changes to objects
	// that match a pattern.  See the package comments for details.
	watch.GlobWatcherServerMethods
	// GetResumeMarker returns the ResumeMarker that points to the current end
	// of the event log. GetResumeMarker() can be called on a batch.
	GetResumeMarker(*context.T, rpc.ServerCall) (watch.ResumeMarker, error)
}

// DatabaseWatcherServerStubMethods is the server interface containing
// DatabaseWatcher methods, as expected by rpc.Server.
// The only difference between this interface and DatabaseWatcherServerMethods
// is the streaming methods.
type DatabaseWatcherServerStubMethods interface {
	// GlobWatcher allows a client to receive updates for changes to objects
	// that match a pattern.  See the package comments for details.
	watch.GlobWatcherServerStubMethods
	// GetResumeMarker returns the ResumeMarker that points to the current end
	// of the event log. GetResumeMarker() can be called on a batch.
	GetResumeMarker(*context.T, rpc.ServerCall) (watch.ResumeMarker, error)
}

// DatabaseWatcherServerStub adds universal methods to DatabaseWatcherServerStubMethods.
type DatabaseWatcherServerStub interface {
	DatabaseWatcherServerStubMethods
	// Describe the DatabaseWatcher interfaces.
	Describe__() []rpc.InterfaceDesc
}

// DatabaseWatcherServer returns a server stub for DatabaseWatcher.
// It converts an implementation of DatabaseWatcherServerMethods into
// an object that may be used by rpc.Server.
func DatabaseWatcherServer(impl DatabaseWatcherServerMethods) DatabaseWatcherServerStub {
	stub := implDatabaseWatcherServerStub{
		impl: impl,
		GlobWatcherServerStub: watch.GlobWatcherServer(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 implDatabaseWatcherServerStub struct {
	impl DatabaseWatcherServerMethods
	watch.GlobWatcherServerStub
	gs *rpc.GlobState
}

func (s implDatabaseWatcherServerStub) GetResumeMarker(ctx *context.T, call rpc.ServerCall) (watch.ResumeMarker, error) {
	return s.impl.GetResumeMarker(ctx, call)
}

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

func (s implDatabaseWatcherServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{DatabaseWatcherDesc, watch.GlobWatcherDesc}
}

// DatabaseWatcherDesc describes the DatabaseWatcher interface.
var DatabaseWatcherDesc rpc.InterfaceDesc = descDatabaseWatcher

// descDatabaseWatcher hides the desc to keep godoc clean.
var descDatabaseWatcher = rpc.InterfaceDesc{
	Name:    "DatabaseWatcher",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// DatabaseWatcher allows a client to watch for updates in the database.\n// For each watched request, the client will receive a reliable stream of watch\n// events without re-ordering. See watch.GlobWatcher for a detailed explanation\n// of the behavior.\n// TODO(rogulenko): Currently the only supported watch patterns are\n// 'table/row*'. Consider changing that.\n//\n// The watching is done by starting a streaming RPC. The argument to the RPC\n// contains the ResumeMarker that points to a particular place in the database\n// event log. The result stream consists of a never-ending sequence of Change\n// messages (until the call fails or is canceled). Each Change contains the\n// Name field in the form \"<tableName>/<rowKey>\" and the Value field of the\n// StoreChange type. If the client has no access to a row specified in a change,\n// that change is excluded from the result stream.\n//\n// The DatabaseWatcher is designed to be used in the following way:\n// 1) begin a read-only batch\n// 2) read all information your app needs\n// 3) read the ResumeMarker\n// 4) abort the batch\n// 5) start watching changes to the data using the ResumeMarker\n// In this configuration the client doesn't miss any changes.",
	Embeds: []rpc.EmbedDesc{
		{"GlobWatcher", "v.io/v23/services/watch", "// GlobWatcher allows a client to receive updates for changes to objects\n// that match a pattern.  See the package comments for details."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "GetResumeMarker",
			Doc:  "// GetResumeMarker returns the ResumeMarker that points to the current end\n// of the event log. GetResumeMarker() can be called on a batch.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // watch.ResumeMarker
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// SyncGroupManagerClientMethods is the client interface
// containing SyncGroupManager methods.
//
// SyncGroupManager is the interface for SyncGroup operations.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncGroupManagerClientMethods interface {
	// GetSyncGroupNames returns the global names of all SyncGroups attached to
	// this database.
	GetSyncGroupNames(*context.T, ...rpc.CallOpt) ([]string, error)
	// CreateSyncGroup creates a new SyncGroup with the given spec.
	//
	// Requires: Client must have at least Read access on the Database; prefix ACL
	// must exist at each SyncGroup prefix; Client must have at least Read access
	// on each of these prefix ACLs.
	CreateSyncGroup(ctx *context.T, sgName string, spec SyncGroupSpec, myInfo SyncGroupMemberInfo, opts ...rpc.CallOpt) error
	// JoinSyncGroup joins the SyncGroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	JoinSyncGroup(ctx *context.T, sgName string, myInfo SyncGroupMemberInfo, opts ...rpc.CallOpt) (spec SyncGroupSpec, err error)
	// LeaveSyncGroup leaves the SyncGroup. Previously synced data will continue
	// to be available.
	//
	// Requires: Client must have at least Read access on the Database.
	LeaveSyncGroup(ctx *context.T, sgName string, opts ...rpc.CallOpt) error
	// DestroySyncGroup destroys the SyncGroup. Previously synced data will
	// continue to be available to all members.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	DestroySyncGroup(ctx *context.T, sgName string, opts ...rpc.CallOpt) error
	// EjectFromSyncGroup ejects a member from the SyncGroup. The ejected member
	// will not be able to sync further, but will retain any data it has already
	// synced.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	EjectFromSyncGroup(ctx *context.T, sgName string, member string, opts ...rpc.CallOpt) error
	// GetSyncGroupSpec gets the SyncGroup spec. version allows for atomic
	// read-modify-write of the spec - see comment for SetSyncGroupSpec.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	GetSyncGroupSpec(ctx *context.T, sgName string, opts ...rpc.CallOpt) (spec SyncGroupSpec, version string, err error)
	// SetSyncGroupSpec sets the SyncGroup spec. version may be either empty or
	// the value from a previous Get. If not empty, Set will only succeed if the
	// current version matches the specified one.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	SetSyncGroupSpec(ctx *context.T, sgName string, spec SyncGroupSpec, version string, opts ...rpc.CallOpt) error
	// GetSyncGroupMembers gets the info objects for members of the SyncGroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	GetSyncGroupMembers(ctx *context.T, sgName string, opts ...rpc.CallOpt) (members map[string]SyncGroupMemberInfo, err error)
}

// SyncGroupManagerClientStub adds universal methods to SyncGroupManagerClientMethods.
type SyncGroupManagerClientStub interface {
	SyncGroupManagerClientMethods
	rpc.UniversalServiceMethods
}

// SyncGroupManagerClient returns a client stub for SyncGroupManager.
func SyncGroupManagerClient(name string) SyncGroupManagerClientStub {
	return implSyncGroupManagerClientStub{name}
}

type implSyncGroupManagerClientStub struct {
	name string
}

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

func (c implSyncGroupManagerClientStub) CreateSyncGroup(ctx *context.T, i0 string, i1 SyncGroupSpec, i2 SyncGroupMemberInfo, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "CreateSyncGroup", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

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

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

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

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

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

func (c implSyncGroupManagerClientStub) SetSyncGroupSpec(ctx *context.T, i0 string, i1 SyncGroupSpec, i2 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "SetSyncGroupSpec", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

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

// SyncGroupManagerServerMethods is the interface a server writer
// implements for SyncGroupManager.
//
// SyncGroupManager is the interface for SyncGroup operations.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncGroupManagerServerMethods interface {
	// GetSyncGroupNames returns the global names of all SyncGroups attached to
	// this database.
	GetSyncGroupNames(*context.T, rpc.ServerCall) ([]string, error)
	// CreateSyncGroup creates a new SyncGroup with the given spec.
	//
	// Requires: Client must have at least Read access on the Database; prefix ACL
	// must exist at each SyncGroup prefix; Client must have at least Read access
	// on each of these prefix ACLs.
	CreateSyncGroup(ctx *context.T, call rpc.ServerCall, sgName string, spec SyncGroupSpec, myInfo SyncGroupMemberInfo) error
	// JoinSyncGroup joins the SyncGroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	JoinSyncGroup(ctx *context.T, call rpc.ServerCall, sgName string, myInfo SyncGroupMemberInfo) (spec SyncGroupSpec, err error)
	// LeaveSyncGroup leaves the SyncGroup. Previously synced data will continue
	// to be available.
	//
	// Requires: Client must have at least Read access on the Database.
	LeaveSyncGroup(ctx *context.T, call rpc.ServerCall, sgName string) error
	// DestroySyncGroup destroys the SyncGroup. Previously synced data will
	// continue to be available to all members.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	DestroySyncGroup(ctx *context.T, call rpc.ServerCall, sgName string) error
	// EjectFromSyncGroup ejects a member from the SyncGroup. The ejected member
	// will not be able to sync further, but will retain any data it has already
	// synced.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	EjectFromSyncGroup(ctx *context.T, call rpc.ServerCall, sgName string, member string) error
	// GetSyncGroupSpec gets the SyncGroup spec. version allows for atomic
	// read-modify-write of the spec - see comment for SetSyncGroupSpec.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	GetSyncGroupSpec(ctx *context.T, call rpc.ServerCall, sgName string) (spec SyncGroupSpec, version string, err error)
	// SetSyncGroupSpec sets the SyncGroup spec. version may be either empty or
	// the value from a previous Get. If not empty, Set will only succeed if the
	// current version matches the specified one.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the SyncGroup ACL.
	SetSyncGroupSpec(ctx *context.T, call rpc.ServerCall, sgName string, spec SyncGroupSpec, version string) error
	// GetSyncGroupMembers gets the info objects for members of the SyncGroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// SyncGroup ACL.
	GetSyncGroupMembers(ctx *context.T, call rpc.ServerCall, sgName string) (members map[string]SyncGroupMemberInfo, err error)
}

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

// SyncGroupManagerServerStub adds universal methods to SyncGroupManagerServerStubMethods.
type SyncGroupManagerServerStub interface {
	SyncGroupManagerServerStubMethods
	// Describe the SyncGroupManager interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implSyncGroupManagerServerStub) GetSyncGroupNames(ctx *context.T, call rpc.ServerCall) ([]string, error) {
	return s.impl.GetSyncGroupNames(ctx, call)
}

func (s implSyncGroupManagerServerStub) CreateSyncGroup(ctx *context.T, call rpc.ServerCall, i0 string, i1 SyncGroupSpec, i2 SyncGroupMemberInfo) error {
	return s.impl.CreateSyncGroup(ctx, call, i0, i1, i2)
}

func (s implSyncGroupManagerServerStub) JoinSyncGroup(ctx *context.T, call rpc.ServerCall, i0 string, i1 SyncGroupMemberInfo) (SyncGroupSpec, error) {
	return s.impl.JoinSyncGroup(ctx, call, i0, i1)
}

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

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

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

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

func (s implSyncGroupManagerServerStub) SetSyncGroupSpec(ctx *context.T, call rpc.ServerCall, i0 string, i1 SyncGroupSpec, i2 string) error {
	return s.impl.SetSyncGroupSpec(ctx, call, i0, i1, i2)
}

func (s implSyncGroupManagerServerStub) GetSyncGroupMembers(ctx *context.T, call rpc.ServerCall, i0 string) (map[string]SyncGroupMemberInfo, error) {
	return s.impl.GetSyncGroupMembers(ctx, call, i0)
}

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

func (s implSyncGroupManagerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{SyncGroupManagerDesc}
}

// SyncGroupManagerDesc describes the SyncGroupManager interface.
var SyncGroupManagerDesc rpc.InterfaceDesc = descSyncGroupManager

// descSyncGroupManager hides the desc to keep godoc clean.
var descSyncGroupManager = rpc.InterfaceDesc{
	Name:    "SyncGroupManager",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// SyncGroupManager is the interface for SyncGroup operations.\n// TODO(hpucha): Add blessings to create/join and add a refresh method.",
	Methods: []rpc.MethodDesc{
		{
			Name: "GetSyncGroupNames",
			Doc:  "// GetSyncGroupNames returns the global names of all SyncGroups attached to\n// this database.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "CreateSyncGroup",
			Doc:  "// CreateSyncGroup creates a new SyncGroup with the given spec.\n//\n// Requires: Client must have at least Read access on the Database; prefix ACL\n// must exist at each SyncGroup prefix; Client must have at least Read access\n// on each of these prefix ACLs.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
				{"spec", ``},   // SyncGroupSpec
				{"myInfo", ``}, // SyncGroupMemberInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "JoinSyncGroup",
			Doc:  "// JoinSyncGroup joins the SyncGroup.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// SyncGroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
				{"myInfo", ``}, // SyncGroupMemberInfo
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``}, // SyncGroupSpec
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "LeaveSyncGroup",
			Doc:  "// LeaveSyncGroup leaves the SyncGroup. Previously synced data will continue\n// to be available.\n//\n// Requires: Client must have at least Read access on the Database.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DestroySyncGroup",
			Doc:  "// DestroySyncGroup destroys the SyncGroup. Previously synced data will\n// continue to be available to all members.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the SyncGroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "EjectFromSyncGroup",
			Doc:  "// EjectFromSyncGroup ejects a member from the SyncGroup. The ejected member\n// will not be able to sync further, but will retain any data it has already\n// synced.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the SyncGroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
				{"member", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetSyncGroupSpec",
			Doc:  "// GetSyncGroupSpec gets the SyncGroup spec. version allows for atomic\n// read-modify-write of the spec - see comment for SetSyncGroupSpec.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// SyncGroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``},    // SyncGroupSpec
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "SetSyncGroupSpec",
			Doc:  "// SetSyncGroupSpec sets the SyncGroup spec. version may be either empty or\n// the value from a previous Get. If not empty, Set will only succeed if the\n// current version matches the specified one.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the SyncGroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``},  // string
				{"spec", ``},    // SyncGroupSpec
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetSyncGroupMembers",
			Doc:  "// GetSyncGroupMembers gets the info objects for members of the SyncGroup.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// SyncGroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"members", ``}, // map[string]SyncGroupMemberInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// BlobManagerClientMethods is the client interface
// containing BlobManager methods.
//
// BlobManager is the interface for blob operations.
type BlobManagerClientMethods interface {
	// API for resumable blob creation (append-only). After commit, a blob
	// is immutable. Before commit, the BlobRef can be used with PutBlob,
	// GetBlobSize, DeleteBlob, and CommitBlob. After commit, PutBlob and
	// CommitBlob can no longer be used. Blob creation can be resumed by
	// obtaining the current blob size with GetBlobSize and appending to the
	// blob via PutBlob.
	//
	// CreateBlob returns a BlobRef for a newly created blob.
	CreateBlob(*context.T, ...rpc.CallOpt) (br BlobRef, err error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(ctx *context.T, br BlobRef, opts ...rpc.CallOpt) (BlobManagerPutBlobClientCall, error)
	// CommitBlob marks the blob as immutable.
	CommitBlob(ctx *context.T, br BlobRef, opts ...rpc.CallOpt) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(ctx *context.T, br BlobRef, opts ...rpc.CallOpt) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(ctx *context.T, br BlobRef, opts ...rpc.CallOpt) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	GetBlob(ctx *context.T, br BlobRef, offset int64, opts ...rpc.CallOpt) (BlobManagerGetBlobClientCall, error)
	// FetchBlob initiates fetching a blob if not locally found. priority
	// controls the network priority of the blob. Higher priority blobs are
	// fetched before the lower priority ones. However an ongoing blob
	// transfer is not interrupted. Status updates are streamed back to the
	// client as fetch is in progress.
	FetchBlob(ctx *context.T, br BlobRef, priority uint64, opts ...rpc.CallOpt) (BlobManagerFetchBlobClientCall, error)
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(ctx *context.T, br BlobRef, opts ...rpc.CallOpt) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(ctx *context.T, br BlobRef, opts ...rpc.CallOpt) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	KeepBlob(ctx *context.T, br BlobRef, rank uint64, opts ...rpc.CallOpt) error
}

// BlobManagerClientStub adds universal methods to BlobManagerClientMethods.
type BlobManagerClientStub interface {
	BlobManagerClientMethods
	rpc.UniversalServiceMethods
}

// BlobManagerClient returns a client stub for BlobManager.
func BlobManagerClient(name string) BlobManagerClientStub {
	return implBlobManagerClientStub{name}
}

type implBlobManagerClientStub struct {
	name string
}

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

func (c implBlobManagerClientStub) PutBlob(ctx *context.T, i0 BlobRef, opts ...rpc.CallOpt) (ocall BlobManagerPutBlobClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "PutBlob", []interface{}{i0}, opts...); err != nil {
		return
	}
	ocall = &implBlobManagerPutBlobClientCall{ClientCall: call}
	return
}

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

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

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

func (c implBlobManagerClientStub) GetBlob(ctx *context.T, i0 BlobRef, i1 int64, opts ...rpc.CallOpt) (ocall BlobManagerGetBlobClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "GetBlob", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implBlobManagerGetBlobClientCall{ClientCall: call}
	return
}

func (c implBlobManagerClientStub) FetchBlob(ctx *context.T, i0 BlobRef, i1 uint64, opts ...rpc.CallOpt) (ocall BlobManagerFetchBlobClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "FetchBlob", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implBlobManagerFetchBlobClientCall{ClientCall: call}
	return
}

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

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

func (c implBlobManagerClientStub) KeepBlob(ctx *context.T, i0 BlobRef, i1 uint64, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "KeepBlob", []interface{}{i0, i1}, nil, opts...)
	return
}

// BlobManagerPutBlobClientStream is the client stream for BlobManager.PutBlob.
type BlobManagerPutBlobClientStream interface {
	// SendStream returns the send side of the BlobManager.PutBlob client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item []byte) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	}
}

// BlobManagerPutBlobClientCall represents the call returned from BlobManager.PutBlob.
type BlobManagerPutBlobClientCall interface {
	BlobManagerPutBlobClientStream
	// 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 implBlobManagerPutBlobClientCall struct {
	rpc.ClientCall
}

func (c *implBlobManagerPutBlobClientCall) SendStream() interface {
	Send(item []byte) error
	Close() error
} {
	return implBlobManagerPutBlobClientCallSend{c}
}

type implBlobManagerPutBlobClientCallSend struct {
	c *implBlobManagerPutBlobClientCall
}

func (c implBlobManagerPutBlobClientCallSend) Send(item []byte) error {
	return c.c.Send(item)
}
func (c implBlobManagerPutBlobClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implBlobManagerPutBlobClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// BlobManagerGetBlobClientStream is the client stream for BlobManager.GetBlob.
type BlobManagerGetBlobClientStream interface {
	// RecvStream returns the receiver side of the BlobManager.GetBlob client stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// BlobManagerGetBlobClientCall represents the call returned from BlobManager.GetBlob.
type BlobManagerGetBlobClientCall interface {
	BlobManagerGetBlobClientStream
	// 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 implBlobManagerGetBlobClientCall struct {
	rpc.ClientCall
	valRecv []byte
	errRecv error
}

func (c *implBlobManagerGetBlobClientCall) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implBlobManagerGetBlobClientCallRecv{c}
}

type implBlobManagerGetBlobClientCallRecv struct {
	c *implBlobManagerGetBlobClientCall
}

func (c implBlobManagerGetBlobClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implBlobManagerGetBlobClientCallRecv) Value() []byte {
	return c.c.valRecv
}
func (c implBlobManagerGetBlobClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implBlobManagerGetBlobClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

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

// BlobManagerFetchBlobClientCall represents the call returned from BlobManager.FetchBlob.
type BlobManagerFetchBlobClientCall interface {
	BlobManagerFetchBlobClientStream
	// 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 implBlobManagerFetchBlobClientCall struct {
	rpc.ClientCall
	valRecv BlobFetchStatus
	errRecv error
}

func (c *implBlobManagerFetchBlobClientCall) RecvStream() interface {
	Advance() bool
	Value() BlobFetchStatus
	Err() error
} {
	return implBlobManagerFetchBlobClientCallRecv{c}
}

type implBlobManagerFetchBlobClientCallRecv struct {
	c *implBlobManagerFetchBlobClientCall
}

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

// BlobManagerServerMethods is the interface a server writer
// implements for BlobManager.
//
// BlobManager is the interface for blob operations.
type BlobManagerServerMethods interface {
	// API for resumable blob creation (append-only). After commit, a blob
	// is immutable. Before commit, the BlobRef can be used with PutBlob,
	// GetBlobSize, DeleteBlob, and CommitBlob. After commit, PutBlob and
	// CommitBlob can no longer be used. Blob creation can be resumed by
	// obtaining the current blob size with GetBlobSize and appending to the
	// blob via PutBlob.
	//
	// CreateBlob returns a BlobRef for a newly created blob.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, err error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(ctx *context.T, call BlobManagerPutBlobServerCall, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	CommitBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(ctx *context.T, call rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	GetBlob(ctx *context.T, call BlobManagerGetBlobServerCall, br BlobRef, offset int64) error
	// FetchBlob initiates fetching a blob if not locally found. priority
	// controls the network priority of the blob. Higher priority blobs are
	// fetched before the lower priority ones. However an ongoing blob
	// transfer is not interrupted. Status updates are streamed back to the
	// client as fetch is in progress.
	FetchBlob(ctx *context.T, call BlobManagerFetchBlobServerCall, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	KeepBlob(ctx *context.T, call rpc.ServerCall, br BlobRef, rank uint64) error
}

// BlobManagerServerStubMethods is the server interface containing
// BlobManager methods, as expected by rpc.Server.
// The only difference between this interface and BlobManagerServerMethods
// is the streaming methods.
type BlobManagerServerStubMethods interface {
	// API for resumable blob creation (append-only). After commit, a blob
	// is immutable. Before commit, the BlobRef can be used with PutBlob,
	// GetBlobSize, DeleteBlob, and CommitBlob. After commit, PutBlob and
	// CommitBlob can no longer be used. Blob creation can be resumed by
	// obtaining the current blob size with GetBlobSize and appending to the
	// blob via PutBlob.
	//
	// CreateBlob returns a BlobRef for a newly created blob.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, err error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(ctx *context.T, call *BlobManagerPutBlobServerCallStub, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	CommitBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(ctx *context.T, call rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	GetBlob(ctx *context.T, call *BlobManagerGetBlobServerCallStub, br BlobRef, offset int64) error
	// FetchBlob initiates fetching a blob if not locally found. priority
	// controls the network priority of the blob. Higher priority blobs are
	// fetched before the lower priority ones. However an ongoing blob
	// transfer is not interrupted. Status updates are streamed back to the
	// client as fetch is in progress.
	FetchBlob(ctx *context.T, call *BlobManagerFetchBlobServerCallStub, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(ctx *context.T, call rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	KeepBlob(ctx *context.T, call rpc.ServerCall, br BlobRef, rank uint64) error
}

// BlobManagerServerStub adds universal methods to BlobManagerServerStubMethods.
type BlobManagerServerStub interface {
	BlobManagerServerStubMethods
	// Describe the BlobManager interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implBlobManagerServerStub) CreateBlob(ctx *context.T, call rpc.ServerCall) (BlobRef, error) {
	return s.impl.CreateBlob(ctx, call)
}

func (s implBlobManagerServerStub) PutBlob(ctx *context.T, call *BlobManagerPutBlobServerCallStub, i0 BlobRef) error {
	return s.impl.PutBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) CommitBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.CommitBlob(ctx, call, i0)
}

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

func (s implBlobManagerServerStub) DeleteBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.DeleteBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) GetBlob(ctx *context.T, call *BlobManagerGetBlobServerCallStub, i0 BlobRef, i1 int64) error {
	return s.impl.GetBlob(ctx, call, i0, i1)
}

func (s implBlobManagerServerStub) FetchBlob(ctx *context.T, call *BlobManagerFetchBlobServerCallStub, i0 BlobRef, i1 uint64) error {
	return s.impl.FetchBlob(ctx, call, i0, i1)
}

func (s implBlobManagerServerStub) PinBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.PinBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) UnpinBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.UnpinBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) KeepBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef, i1 uint64) error {
	return s.impl.KeepBlob(ctx, call, i0, i1)
}

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

func (s implBlobManagerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{BlobManagerDesc}
}

// BlobManagerDesc describes the BlobManager interface.
var BlobManagerDesc rpc.InterfaceDesc = descBlobManager

// descBlobManager hides the desc to keep godoc clean.
var descBlobManager = rpc.InterfaceDesc{
	Name:    "BlobManager",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// BlobManager is the interface for blob operations.",
	Methods: []rpc.MethodDesc{
		{
			Name: "CreateBlob",
			Doc:  "// API for resumable blob creation (append-only). After commit, a blob\n// is immutable. Before commit, the BlobRef can be used with PutBlob,\n// GetBlobSize, DeleteBlob, and CommitBlob. After commit, PutBlob and\n// CommitBlob can no longer be used. Blob creation can be resumed by\n// obtaining the current blob size with GetBlobSize and appending to the\n// blob via PutBlob.\n//\n// CreateBlob returns a BlobRef for a newly created blob.",
			OutArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "PutBlob",
			Doc:  "// PutBlob appends the byte stream to the blob.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "CommitBlob",
			Doc:  "// CommitBlob marks the blob as immutable.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "GetBlobSize",
			Doc:  "// GetBlobSize returns the count of bytes written as part of the blob\n// (committed or uncommitted).",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DeleteBlob",
			Doc:  "// DeleteBlob locally deletes the blob (committed or uncommitted).",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "GetBlob",
			Doc:  "// GetBlob returns the byte stream from a committed blob starting at offset.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},     // BlobRef
				{"offset", ``}, // int64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "FetchBlob",
			Doc:  "// FetchBlob initiates fetching a blob if not locally found. priority\n// controls the network priority of the blob. Higher priority blobs are\n// fetched before the lower priority ones. However an ongoing blob\n// transfer is not interrupted. Status updates are streamed back to the\n// client as fetch is in progress.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},       // BlobRef
				{"priority", ``}, // uint64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "PinBlob",
			Doc:  "// PinBlob locally pins the blob so that it is not evicted.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "UnpinBlob",
			Doc:  "// UnpinBlob locally unpins the blob so that it can be evicted if needed.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "KeepBlob",
			Doc:  "// KeepBlob locally caches the blob with the specified rank. Lower\n// ranked blobs are more eagerly evicted.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},   // BlobRef
				{"rank", ``}, // uint64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// BlobManagerPutBlobServerStream is the server stream for BlobManager.PutBlob.
type BlobManagerPutBlobServerStream interface {
	// RecvStream returns the receiver side of the BlobManager.PutBlob server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// BlobManagerPutBlobServerCall represents the context passed to BlobManager.PutBlob.
type BlobManagerPutBlobServerCall interface {
	rpc.ServerCall
	BlobManagerPutBlobServerStream
}

// BlobManagerPutBlobServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements BlobManagerPutBlobServerCall.
type BlobManagerPutBlobServerCallStub struct {
	rpc.StreamServerCall
	valRecv []byte
	errRecv error
}

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

// RecvStream returns the receiver side of the BlobManager.PutBlob server stream.
func (s *BlobManagerPutBlobServerCallStub) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implBlobManagerPutBlobServerCallRecv{s}
}

type implBlobManagerPutBlobServerCallRecv struct {
	s *BlobManagerPutBlobServerCallStub
}

func (s implBlobManagerPutBlobServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implBlobManagerPutBlobServerCallRecv) Value() []byte {
	return s.s.valRecv
}
func (s implBlobManagerPutBlobServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}

// BlobManagerGetBlobServerStream is the server stream for BlobManager.GetBlob.
type BlobManagerGetBlobServerStream interface {
	// SendStream returns the send side of the BlobManager.GetBlob server stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors encountered
		// while sending.  Blocks if there is no buffer space; will unblock when
		// buffer space is available.
		Send(item []byte) error
	}
}

// BlobManagerGetBlobServerCall represents the context passed to BlobManager.GetBlob.
type BlobManagerGetBlobServerCall interface {
	rpc.ServerCall
	BlobManagerGetBlobServerStream
}

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

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

// SendStream returns the send side of the BlobManager.GetBlob server stream.
func (s *BlobManagerGetBlobServerCallStub) SendStream() interface {
	Send(item []byte) error
} {
	return implBlobManagerGetBlobServerCallSend{s}
}

type implBlobManagerGetBlobServerCallSend struct {
	s *BlobManagerGetBlobServerCallStub
}

func (s implBlobManagerGetBlobServerCallSend) Send(item []byte) error {
	return s.s.Send(item)
}

// BlobManagerFetchBlobServerStream is the server stream for BlobManager.FetchBlob.
type BlobManagerFetchBlobServerStream interface {
	// SendStream returns the send side of the BlobManager.FetchBlob 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 BlobFetchStatus) error
	}
}

// BlobManagerFetchBlobServerCall represents the context passed to BlobManager.FetchBlob.
type BlobManagerFetchBlobServerCall interface {
	rpc.ServerCall
	BlobManagerFetchBlobServerStream
}

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

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

// SendStream returns the send side of the BlobManager.FetchBlob server stream.
func (s *BlobManagerFetchBlobServerCallStub) SendStream() interface {
	Send(item BlobFetchStatus) error
} {
	return implBlobManagerFetchBlobServerCallSend{s}
}

type implBlobManagerFetchBlobServerCallSend struct {
	s *BlobManagerFetchBlobServerCallStub
}

func (s implBlobManagerFetchBlobServerCallSend) Send(item BlobFetchStatus) error {
	return s.s.Send(item)
}

// SchemaManagerClientMethods is the client interface
// containing SchemaManager methods.
//
// SchemaManager implements the API for managing schema metadata attached
// to a Database.
type SchemaManagerClientMethods interface {
	// GetSchemaMetadata retrieves schema metadata for this database.
	//
	// Requires: Client must have at least Read access on the Database.
	GetSchemaMetadata(*context.T, ...rpc.CallOpt) (SchemaMetadata, error)
	// SetSchemaMetadata stores schema metadata for this database.
	//
	// Requires: Client must have at least Write access on the Database.
	SetSchemaMetadata(ctx *context.T, metadata SchemaMetadata, opts ...rpc.CallOpt) error
}

// SchemaManagerClientStub adds universal methods to SchemaManagerClientMethods.
type SchemaManagerClientStub interface {
	SchemaManagerClientMethods
	rpc.UniversalServiceMethods
}

// SchemaManagerClient returns a client stub for SchemaManager.
func SchemaManagerClient(name string) SchemaManagerClientStub {
	return implSchemaManagerClientStub{name}
}

type implSchemaManagerClientStub struct {
	name string
}

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

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

// SchemaManagerServerMethods is the interface a server writer
// implements for SchemaManager.
//
// SchemaManager implements the API for managing schema metadata attached
// to a Database.
type SchemaManagerServerMethods interface {
	// GetSchemaMetadata retrieves schema metadata for this database.
	//
	// Requires: Client must have at least Read access on the Database.
	GetSchemaMetadata(*context.T, rpc.ServerCall) (SchemaMetadata, error)
	// SetSchemaMetadata stores schema metadata for this database.
	//
	// Requires: Client must have at least Write access on the Database.
	SetSchemaMetadata(ctx *context.T, call rpc.ServerCall, metadata SchemaMetadata) error
}

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

// SchemaManagerServerStub adds universal methods to SchemaManagerServerStubMethods.
type SchemaManagerServerStub interface {
	SchemaManagerServerStubMethods
	// Describe the SchemaManager interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implSchemaManagerServerStub) GetSchemaMetadata(ctx *context.T, call rpc.ServerCall) (SchemaMetadata, error) {
	return s.impl.GetSchemaMetadata(ctx, call)
}

func (s implSchemaManagerServerStub) SetSchemaMetadata(ctx *context.T, call rpc.ServerCall, i0 SchemaMetadata) error {
	return s.impl.SetSchemaMetadata(ctx, call, i0)
}

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

func (s implSchemaManagerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{SchemaManagerDesc}
}

// SchemaManagerDesc describes the SchemaManager interface.
var SchemaManagerDesc rpc.InterfaceDesc = descSchemaManager

// descSchemaManager hides the desc to keep godoc clean.
var descSchemaManager = rpc.InterfaceDesc{
	Name:    "SchemaManager",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// SchemaManager implements the API for managing schema metadata attached\n// to a Database.",
	Methods: []rpc.MethodDesc{
		{
			Name: "GetSchemaMetadata",
			Doc:  "// GetSchemaMetadata retrieves schema metadata for this database.\n//\n// Requires: Client must have at least Read access on the Database.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // SchemaMetadata
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "SetSchemaMetadata",
			Doc:  "// SetSchemaMetadata stores schema metadata for this database.\n//\n// Requires: Client must have at least Write access on the Database.",
			InArgs: []rpc.ArgDesc{
				{"metadata", ``}, // SchemaMetadata
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// ConflictManagerClientMethods is the client interface
// containing ConflictManager methods.
//
// ConflictManager interface provides all the methods necessary to handle
// conflict resolution for a given database.
type ConflictManagerClientMethods interface {
	// StartConflictResolver registers a resolver for the database that is
	// associated with this ConflictManager and creates a stream to receive
	// conflicts and send resolutions.
	// Batches of ConflictInfos will be sent over with the Continued field
	// within the ConflictInfo representing the batch boundary. Client must
	// respond with a batch of ResolutionInfos in the same fashion.
	// A key is under conflict if two different values were written to it
	// concurrently (in logical time), i.e. neither value is an ancestor of the
	// other in the history graph.
	// A key under conflict can be a part of a batch committed on local or
	// remote or both syncbases. ConflictInfos for all keys in these two batches
	// are grouped together. These keys may themselves be under conflict; the
	// presented batch is a transitive closure of all batches containing keys
	// under conflict.
	// For example, for local batch {key1, key2} and remote batch {key1, key3},
	// the batch sent for conflict resolution will be {key1, key2, key3}.
	// If there was another concurrent batch {key2, key4}, then the batch sent
	// for conflict resolution will be {key1, key2, key3, key4}.
	StartConflictResolver(*context.T, ...rpc.CallOpt) (ConflictManagerStartConflictResolverClientCall, error)
}

// ConflictManagerClientStub adds universal methods to ConflictManagerClientMethods.
type ConflictManagerClientStub interface {
	ConflictManagerClientMethods
	rpc.UniversalServiceMethods
}

// ConflictManagerClient returns a client stub for ConflictManager.
func ConflictManagerClient(name string) ConflictManagerClientStub {
	return implConflictManagerClientStub{name}
}

type implConflictManagerClientStub struct {
	name string
}

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

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

// ConflictManagerStartConflictResolverClientCall represents the call returned from ConflictManager.StartConflictResolver.
type ConflictManagerStartConflictResolverClientCall interface {
	ConflictManagerStartConflictResolverClientStream
	// 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 implConflictManagerStartConflictResolverClientCall struct {
	rpc.ClientCall
	valRecv ConflictInfo
	errRecv error
}

func (c *implConflictManagerStartConflictResolverClientCall) RecvStream() interface {
	Advance() bool
	Value() ConflictInfo
	Err() error
} {
	return implConflictManagerStartConflictResolverClientCallRecv{c}
}

type implConflictManagerStartConflictResolverClientCallRecv struct {
	c *implConflictManagerStartConflictResolverClientCall
}

func (c implConflictManagerStartConflictResolverClientCallRecv) Advance() bool {
	c.c.valRecv = ConflictInfo{}
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implConflictManagerStartConflictResolverClientCallRecv) Value() ConflictInfo {
	return c.c.valRecv
}
func (c implConflictManagerStartConflictResolverClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implConflictManagerStartConflictResolverClientCall) SendStream() interface {
	Send(item ResolutionInfo) error
	Close() error
} {
	return implConflictManagerStartConflictResolverClientCallSend{c}
}

type implConflictManagerStartConflictResolverClientCallSend struct {
	c *implConflictManagerStartConflictResolverClientCall
}

func (c implConflictManagerStartConflictResolverClientCallSend) Send(item ResolutionInfo) error {
	return c.c.Send(item)
}
func (c implConflictManagerStartConflictResolverClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implConflictManagerStartConflictResolverClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// ConflictManagerServerMethods is the interface a server writer
// implements for ConflictManager.
//
// ConflictManager interface provides all the methods necessary to handle
// conflict resolution for a given database.
type ConflictManagerServerMethods interface {
	// StartConflictResolver registers a resolver for the database that is
	// associated with this ConflictManager and creates a stream to receive
	// conflicts and send resolutions.
	// Batches of ConflictInfos will be sent over with the Continued field
	// within the ConflictInfo representing the batch boundary. Client must
	// respond with a batch of ResolutionInfos in the same fashion.
	// A key is under conflict if two different values were written to it
	// concurrently (in logical time), i.e. neither value is an ancestor of the
	// other in the history graph.
	// A key under conflict can be a part of a batch committed on local or
	// remote or both syncbases. ConflictInfos for all keys in these two batches
	// are grouped together. These keys may themselves be under conflict; the
	// presented batch is a transitive closure of all batches containing keys
	// under conflict.
	// For example, for local batch {key1, key2} and remote batch {key1, key3},
	// the batch sent for conflict resolution will be {key1, key2, key3}.
	// If there was another concurrent batch {key2, key4}, then the batch sent
	// for conflict resolution will be {key1, key2, key3, key4}.
	StartConflictResolver(*context.T, ConflictManagerStartConflictResolverServerCall) error
}

// ConflictManagerServerStubMethods is the server interface containing
// ConflictManager methods, as expected by rpc.Server.
// The only difference between this interface and ConflictManagerServerMethods
// is the streaming methods.
type ConflictManagerServerStubMethods interface {
	// StartConflictResolver registers a resolver for the database that is
	// associated with this ConflictManager and creates a stream to receive
	// conflicts and send resolutions.
	// Batches of ConflictInfos will be sent over with the Continued field
	// within the ConflictInfo representing the batch boundary. Client must
	// respond with a batch of ResolutionInfos in the same fashion.
	// A key is under conflict if two different values were written to it
	// concurrently (in logical time), i.e. neither value is an ancestor of the
	// other in the history graph.
	// A key under conflict can be a part of a batch committed on local or
	// remote or both syncbases. ConflictInfos for all keys in these two batches
	// are grouped together. These keys may themselves be under conflict; the
	// presented batch is a transitive closure of all batches containing keys
	// under conflict.
	// For example, for local batch {key1, key2} and remote batch {key1, key3},
	// the batch sent for conflict resolution will be {key1, key2, key3}.
	// If there was another concurrent batch {key2, key4}, then the batch sent
	// for conflict resolution will be {key1, key2, key3, key4}.
	StartConflictResolver(*context.T, *ConflictManagerStartConflictResolverServerCallStub) error
}

// ConflictManagerServerStub adds universal methods to ConflictManagerServerStubMethods.
type ConflictManagerServerStub interface {
	ConflictManagerServerStubMethods
	// Describe the ConflictManager interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implConflictManagerServerStub) StartConflictResolver(ctx *context.T, call *ConflictManagerStartConflictResolverServerCallStub) error {
	return s.impl.StartConflictResolver(ctx, call)
}

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

func (s implConflictManagerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ConflictManagerDesc}
}

// ConflictManagerDesc describes the ConflictManager interface.
var ConflictManagerDesc rpc.InterfaceDesc = descConflictManager

// descConflictManager hides the desc to keep godoc clean.
var descConflictManager = rpc.InterfaceDesc{
	Name:    "ConflictManager",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// ConflictManager interface provides all the methods necessary to handle\n// conflict resolution for a given database.",
	Methods: []rpc.MethodDesc{
		{
			Name: "StartConflictResolver",
			Doc:  "// StartConflictResolver registers a resolver for the database that is\n// associated with this ConflictManager and creates a stream to receive\n// conflicts and send resolutions.\n// Batches of ConflictInfos will be sent over with the Continued field\n// within the ConflictInfo representing the batch boundary. Client must\n// respond with a batch of ResolutionInfos in the same fashion.\n// A key is under conflict if two different values were written to it\n// concurrently (in logical time), i.e. neither value is an ancestor of the\n// other in the history graph.\n// A key under conflict can be a part of a batch committed on local or\n// remote or both syncbases. ConflictInfos for all keys in these two batches\n// are grouped together. These keys may themselves be under conflict; the\n// presented batch is a transitive closure of all batches containing keys\n// under conflict.\n// For example, for local batch {key1, key2} and remote batch {key1, key3},\n// the batch sent for conflict resolution will be {key1, key2, key3}.\n// If there was another concurrent batch {key2, key4}, then the batch sent\n// for conflict resolution will be {key1, key2, key3, key4}.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

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

// ConflictManagerStartConflictResolverServerCall represents the context passed to ConflictManager.StartConflictResolver.
type ConflictManagerStartConflictResolverServerCall interface {
	rpc.ServerCall
	ConflictManagerStartConflictResolverServerStream
}

// ConflictManagerStartConflictResolverServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements ConflictManagerStartConflictResolverServerCall.
type ConflictManagerStartConflictResolverServerCallStub struct {
	rpc.StreamServerCall
	valRecv ResolutionInfo
	errRecv error
}

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

// RecvStream returns the receiver side of the ConflictManager.StartConflictResolver server stream.
func (s *ConflictManagerStartConflictResolverServerCallStub) RecvStream() interface {
	Advance() bool
	Value() ResolutionInfo
	Err() error
} {
	return implConflictManagerStartConflictResolverServerCallRecv{s}
}

type implConflictManagerStartConflictResolverServerCallRecv struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

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

// SendStream returns the send side of the ConflictManager.StartConflictResolver server stream.
func (s *ConflictManagerStartConflictResolverServerCallStub) SendStream() interface {
	Send(item ConflictInfo) error
} {
	return implConflictManagerStartConflictResolverServerCallSend{s}
}

type implConflictManagerStartConflictResolverServerCallSend struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

func (s implConflictManagerStartConflictResolverServerCallSend) Send(item ConflictInfo) error {
	return s.s.Send(item)
}

// DatabaseClientMethods is the client interface
// containing Database methods.
//
// Database represents a collection of Tables. Batches, queries, sync, watch,
// etc. all operate at the Database level.
// Database.Glob operates over Table names.
// Param schemaVersion is the version number that the client expects the database
// to be at. To disable schema version checking, pass -1.
//
// TODO(sadovsky): Add Watch method.
type DatabaseClientMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectClientMethods
	// DatabaseWatcher allows a client to watch for updates in the database.
	// For each watched request, the client will receive a reliable stream of watch
	// events without re-ordering. See watch.GlobWatcher for a detailed explanation
	// of the behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// 'table/row*'. Consider changing that.
	//
	// The watching is done by starting a streaming RPC. The argument to the RPC
	// contains the ResumeMarker that points to a particular place in the database
	// event log. The result stream consists of a never-ending sequence of Change
	// messages (until the call fails or is canceled). Each Change contains the
	// Name field in the form "<tableName>/<rowKey>" and the Value field of the
	// StoreChange type. If the client has no access to a row specified in a change,
	// that change is excluded from the result stream.
	//
	// The DatabaseWatcher is designed to be used in the following way:
	// 1) begin a read-only batch
	// 2) read all information your app needs
	// 3) read the ResumeMarker
	// 4) abort the batch
	// 5) start watching changes to the data using the ResumeMarker
	// In this configuration the client doesn't miss any changes.
	DatabaseWatcherClientMethods
	// SyncGroupManager is the interface for SyncGroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncGroupManagerClientMethods
	// BlobManager is the interface for blob operations.
	BlobManagerClientMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerClientMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerClientMethods
	// Create creates this Database.
	// If perms is nil, we inherit (copy) the App perms.
	// Create requires the caller to have Write permission at the App.
	Create(ctx *context.T, metadata *SchemaMetadata, perms access.Permissions, opts ...rpc.CallOpt) error
	// Delete deletes this Database.
	Delete(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) (bool, error)
	// Exec executes a syncQL query and returns all results as specified by in the
	// query's select clause. Concurrency semantics are documented in model.go.
	Exec(ctx *context.T, schemaVersion int32, query string, opts ...rpc.CallOpt) (DatabaseExecClientCall, error)
	// BeginBatch creates a new batch. It returns an App-relative name for a
	// Database handle bound to this batch. If this Database is already bound to a
	// batch, BeginBatch() will fail with ErrBoundToBatch. Concurrency semantics
	// are documented in model.go.
	// TODO(sadovsky): make BatchOptions optional
	BeginBatch(ctx *context.T, schemaVersion int32, bo BatchOptions, opts ...rpc.CallOpt) (string, error)
	// Commit persists the pending changes to the database.
	// If this Database is not bound to a batch, Commit() will fail with
	// ErrNotBoundToBatch.
	Commit(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) error
	// Abort notifies the server that any pending changes can be discarded.
	// It is not strictly required, but it may allow the server to release locks
	// or other resources sooner than if it was not called.
	// If this Database is not bound to a batch, Abort() will fail with
	// ErrNotBoundToBatch.
	Abort(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) error
}

// DatabaseClientStub adds universal methods to DatabaseClientMethods.
type DatabaseClientStub interface {
	DatabaseClientMethods
	rpc.UniversalServiceMethods
}

// DatabaseClient returns a client stub for Database.
func DatabaseClient(name string) DatabaseClientStub {
	return implDatabaseClientStub{name, permissions.ObjectClient(name), DatabaseWatcherClient(name), SyncGroupManagerClient(name), BlobManagerClient(name), SchemaManagerClient(name), ConflictManagerClient(name)}
}

type implDatabaseClientStub struct {
	name string

	permissions.ObjectClientStub
	DatabaseWatcherClientStub
	SyncGroupManagerClientStub
	BlobManagerClientStub
	SchemaManagerClientStub
	ConflictManagerClientStub
}

func (c implDatabaseClientStub) Create(ctx *context.T, i0 *SchemaMetadata, i1 access.Permissions, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Create", []interface{}{i0, i1}, nil, opts...)
	return
}

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

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

func (c implDatabaseClientStub) Exec(ctx *context.T, i0 int32, i1 string, opts ...rpc.CallOpt) (ocall DatabaseExecClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Exec", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implDatabaseExecClientCall{ClientCall: call}
	return
}

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

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

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

// DatabaseExecClientStream is the client stream for Database.Exec.
type DatabaseExecClientStream interface {
	// RecvStream returns the receiver side of the Database.Exec 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() []*vdl.Value
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// DatabaseExecClientCall represents the call returned from Database.Exec.
type DatabaseExecClientCall interface {
	DatabaseExecClientStream
	// 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 implDatabaseExecClientCall struct {
	rpc.ClientCall
	valRecv []*vdl.Value
	errRecv error
}

func (c *implDatabaseExecClientCall) RecvStream() interface {
	Advance() bool
	Value() []*vdl.Value
	Err() error
} {
	return implDatabaseExecClientCallRecv{c}
}

type implDatabaseExecClientCallRecv struct {
	c *implDatabaseExecClientCall
}

func (c implDatabaseExecClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implDatabaseExecClientCallRecv) Value() []*vdl.Value {
	return c.c.valRecv
}
func (c implDatabaseExecClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implDatabaseExecClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// DatabaseServerMethods is the interface a server writer
// implements for Database.
//
// Database represents a collection of Tables. Batches, queries, sync, watch,
// etc. all operate at the Database level.
// Database.Glob operates over Table names.
// Param schemaVersion is the version number that the client expects the database
// to be at. To disable schema version checking, pass -1.
//
// TODO(sadovsky): Add Watch method.
type DatabaseServerMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerMethods
	// DatabaseWatcher allows a client to watch for updates in the database.
	// For each watched request, the client will receive a reliable stream of watch
	// events without re-ordering. See watch.GlobWatcher for a detailed explanation
	// of the behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// 'table/row*'. Consider changing that.
	//
	// The watching is done by starting a streaming RPC. The argument to the RPC
	// contains the ResumeMarker that points to a particular place in the database
	// event log. The result stream consists of a never-ending sequence of Change
	// messages (until the call fails or is canceled). Each Change contains the
	// Name field in the form "<tableName>/<rowKey>" and the Value field of the
	// StoreChange type. If the client has no access to a row specified in a change,
	// that change is excluded from the result stream.
	//
	// The DatabaseWatcher is designed to be used in the following way:
	// 1) begin a read-only batch
	// 2) read all information your app needs
	// 3) read the ResumeMarker
	// 4) abort the batch
	// 5) start watching changes to the data using the ResumeMarker
	// In this configuration the client doesn't miss any changes.
	DatabaseWatcherServerMethods
	// SyncGroupManager is the interface for SyncGroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncGroupManagerServerMethods
	// BlobManager is the interface for blob operations.
	BlobManagerServerMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerServerMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerServerMethods
	// Create creates this Database.
	// If perms is nil, we inherit (copy) the App perms.
	// Create requires the caller to have Write permission at the App.
	Create(ctx *context.T, call rpc.ServerCall, metadata *SchemaMetadata, perms access.Permissions) error
	// Delete deletes this Database.
	Delete(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, call rpc.ServerCall, schemaVersion int32) (bool, error)
	// Exec executes a syncQL query and returns all results as specified by in the
	// query's select clause. Concurrency semantics are documented in model.go.
	Exec(ctx *context.T, call DatabaseExecServerCall, schemaVersion int32, query string) error
	// BeginBatch creates a new batch. It returns an App-relative name for a
	// Database handle bound to this batch. If this Database is already bound to a
	// batch, BeginBatch() will fail with ErrBoundToBatch. Concurrency semantics
	// are documented in model.go.
	// TODO(sadovsky): make BatchOptions optional
	BeginBatch(ctx *context.T, call rpc.ServerCall, schemaVersion int32, bo BatchOptions) (string, error)
	// Commit persists the pending changes to the database.
	// If this Database is not bound to a batch, Commit() will fail with
	// ErrNotBoundToBatch.
	Commit(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
	// Abort notifies the server that any pending changes can be discarded.
	// It is not strictly required, but it may allow the server to release locks
	// or other resources sooner than if it was not called.
	// If this Database is not bound to a batch, Abort() will fail with
	// ErrNotBoundToBatch.
	Abort(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
}

// DatabaseServerStubMethods is the server interface containing
// Database methods, as expected by rpc.Server.
// The only difference between this interface and DatabaseServerMethods
// is the streaming methods.
type DatabaseServerStubMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerStubMethods
	// DatabaseWatcher allows a client to watch for updates in the database.
	// For each watched request, the client will receive a reliable stream of watch
	// events without re-ordering. See watch.GlobWatcher for a detailed explanation
	// of the behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// 'table/row*'. Consider changing that.
	//
	// The watching is done by starting a streaming RPC. The argument to the RPC
	// contains the ResumeMarker that points to a particular place in the database
	// event log. The result stream consists of a never-ending sequence of Change
	// messages (until the call fails or is canceled). Each Change contains the
	// Name field in the form "<tableName>/<rowKey>" and the Value field of the
	// StoreChange type. If the client has no access to a row specified in a change,
	// that change is excluded from the result stream.
	//
	// The DatabaseWatcher is designed to be used in the following way:
	// 1) begin a read-only batch
	// 2) read all information your app needs
	// 3) read the ResumeMarker
	// 4) abort the batch
	// 5) start watching changes to the data using the ResumeMarker
	// In this configuration the client doesn't miss any changes.
	DatabaseWatcherServerStubMethods
	// SyncGroupManager is the interface for SyncGroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncGroupManagerServerStubMethods
	// BlobManager is the interface for blob operations.
	BlobManagerServerStubMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerServerStubMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerServerStubMethods
	// Create creates this Database.
	// If perms is nil, we inherit (copy) the App perms.
	// Create requires the caller to have Write permission at the App.
	Create(ctx *context.T, call rpc.ServerCall, metadata *SchemaMetadata, perms access.Permissions) error
	// Delete deletes this Database.
	Delete(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, call rpc.ServerCall, schemaVersion int32) (bool, error)
	// Exec executes a syncQL query and returns all results as specified by in the
	// query's select clause. Concurrency semantics are documented in model.go.
	Exec(ctx *context.T, call *DatabaseExecServerCallStub, schemaVersion int32, query string) error
	// BeginBatch creates a new batch. It returns an App-relative name for a
	// Database handle bound to this batch. If this Database is already bound to a
	// batch, BeginBatch() will fail with ErrBoundToBatch. Concurrency semantics
	// are documented in model.go.
	// TODO(sadovsky): make BatchOptions optional
	BeginBatch(ctx *context.T, call rpc.ServerCall, schemaVersion int32, bo BatchOptions) (string, error)
	// Commit persists the pending changes to the database.
	// If this Database is not bound to a batch, Commit() will fail with
	// ErrNotBoundToBatch.
	Commit(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
	// Abort notifies the server that any pending changes can be discarded.
	// It is not strictly required, but it may allow the server to release locks
	// or other resources sooner than if it was not called.
	// If this Database is not bound to a batch, Abort() will fail with
	// ErrNotBoundToBatch.
	Abort(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
}

// DatabaseServerStub adds universal methods to DatabaseServerStubMethods.
type DatabaseServerStub interface {
	DatabaseServerStubMethods
	// Describe the Database interfaces.
	Describe__() []rpc.InterfaceDesc
}

// DatabaseServer returns a server stub for Database.
// It converts an implementation of DatabaseServerMethods into
// an object that may be used by rpc.Server.
func DatabaseServer(impl DatabaseServerMethods) DatabaseServerStub {
	stub := implDatabaseServerStub{
		impl:                       impl,
		ObjectServerStub:           permissions.ObjectServer(impl),
		DatabaseWatcherServerStub:  DatabaseWatcherServer(impl),
		SyncGroupManagerServerStub: SyncGroupManagerServer(impl),
		BlobManagerServerStub:      BlobManagerServer(impl),
		SchemaManagerServerStub:    SchemaManagerServer(impl),
		ConflictManagerServerStub:  ConflictManagerServer(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 implDatabaseServerStub struct {
	impl DatabaseServerMethods
	permissions.ObjectServerStub
	DatabaseWatcherServerStub
	SyncGroupManagerServerStub
	BlobManagerServerStub
	SchemaManagerServerStub
	ConflictManagerServerStub
	gs *rpc.GlobState
}

func (s implDatabaseServerStub) Create(ctx *context.T, call rpc.ServerCall, i0 *SchemaMetadata, i1 access.Permissions) error {
	return s.impl.Create(ctx, call, i0, i1)
}

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

func (s implDatabaseServerStub) Exists(ctx *context.T, call rpc.ServerCall, i0 int32) (bool, error) {
	return s.impl.Exists(ctx, call, i0)
}

func (s implDatabaseServerStub) Exec(ctx *context.T, call *DatabaseExecServerCallStub, i0 int32, i1 string) error {
	return s.impl.Exec(ctx, call, i0, i1)
}

func (s implDatabaseServerStub) BeginBatch(ctx *context.T, call rpc.ServerCall, i0 int32, i1 BatchOptions) (string, error) {
	return s.impl.BeginBatch(ctx, call, i0, i1)
}

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

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

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

func (s implDatabaseServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{DatabaseDesc, permissions.ObjectDesc, DatabaseWatcherDesc, watch.GlobWatcherDesc, SyncGroupManagerDesc, BlobManagerDesc, SchemaManagerDesc, ConflictManagerDesc}
}

// DatabaseDesc describes the Database interface.
var DatabaseDesc rpc.InterfaceDesc = descDatabase

// descDatabase hides the desc to keep godoc clean.
var descDatabase = rpc.InterfaceDesc{
	Name:    "Database",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// Database represents a collection of Tables. Batches, queries, sync, watch,\n// etc. all operate at the Database level.\n// Database.Glob operates over Table names.\n// Param schemaVersion is the version number that the client expects the database\n// to be at. To disable schema version checking, pass -1.\n//\n// TODO(sadovsky): Add Watch method.",
	Embeds: []rpc.EmbedDesc{
		{"Object", "v.io/v23/services/permissions", "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"},
		{"DatabaseWatcher", "v.io/syncbase/v23/services/syncbase/nosql", "// DatabaseWatcher allows a client to watch for updates in the database.\n// For each watched request, the client will receive a reliable stream of watch\n// events without re-ordering. See watch.GlobWatcher for a detailed explanation\n// of the behavior.\n// TODO(rogulenko): Currently the only supported watch patterns are\n// 'table/row*'. Consider changing that.\n//\n// The watching is done by starting a streaming RPC. The argument to the RPC\n// contains the ResumeMarker that points to a particular place in the database\n// event log. The result stream consists of a never-ending sequence of Change\n// messages (until the call fails or is canceled). Each Change contains the\n// Name field in the form \"<tableName>/<rowKey>\" and the Value field of the\n// StoreChange type. If the client has no access to a row specified in a change,\n// that change is excluded from the result stream.\n//\n// The DatabaseWatcher is designed to be used in the following way:\n// 1) begin a read-only batch\n// 2) read all information your app needs\n// 3) read the ResumeMarker\n// 4) abort the batch\n// 5) start watching changes to the data using the ResumeMarker\n// In this configuration the client doesn't miss any changes."},
		{"SyncGroupManager", "v.io/syncbase/v23/services/syncbase/nosql", "// SyncGroupManager is the interface for SyncGroup operations.\n// TODO(hpucha): Add blessings to create/join and add a refresh method."},
		{"BlobManager", "v.io/syncbase/v23/services/syncbase/nosql", "// BlobManager is the interface for blob operations."},
		{"SchemaManager", "v.io/syncbase/v23/services/syncbase/nosql", "// SchemaManager implements the API for managing schema metadata attached\n// to a Database."},
		{"ConflictManager", "v.io/syncbase/v23/services/syncbase/nosql", "// ConflictManager interface provides all the methods necessary to handle\n// conflict resolution for a given database."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Database.\n// If perms is nil, we inherit (copy) the App perms.\n// Create requires the caller to have Write permission at the App.",
			InArgs: []rpc.ArgDesc{
				{"metadata", ``}, // *SchemaMetadata
				{"perms", ``},    // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Database.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Database exists. Insufficient permissions\n// cause Exists to return false instead of an error.\n// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy\n// do not exist.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Exec",
			Doc:  "// Exec executes a syncQL query and returns all results as specified by in the\n// query's select clause. Concurrency semantics are documented in model.go.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"query", ``},         // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "BeginBatch",
			Doc:  "// BeginBatch creates a new batch. It returns an App-relative name for a\n// Database handle bound to this batch. If this Database is already bound to a\n// batch, BeginBatch() will fail with ErrBoundToBatch. Concurrency semantics\n// are documented in model.go.\n// TODO(sadovsky): make BatchOptions optional",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"bo", ``},            // BatchOptions
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Commit",
			Doc:  "// Commit persists the pending changes to the database.\n// If this Database is not bound to a batch, Commit() will fail with\n// ErrNotBoundToBatch.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Abort",
			Doc:  "// Abort notifies the server that any pending changes can be discarded.\n// It is not strictly required, but it may allow the server to release locks\n// or other resources sooner than if it was not called.\n// If this Database is not bound to a batch, Abort() will fail with\n// ErrNotBoundToBatch.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// DatabaseExecServerStream is the server stream for Database.Exec.
type DatabaseExecServerStream interface {
	// SendStream returns the send side of the Database.Exec 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 []*vdl.Value) error
	}
}

// DatabaseExecServerCall represents the context passed to Database.Exec.
type DatabaseExecServerCall interface {
	rpc.ServerCall
	DatabaseExecServerStream
}

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

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

// SendStream returns the send side of the Database.Exec server stream.
func (s *DatabaseExecServerCallStub) SendStream() interface {
	Send(item []*vdl.Value) error
} {
	return implDatabaseExecServerCallSend{s}
}

type implDatabaseExecServerCallSend struct {
	s *DatabaseExecServerCallStub
}

func (s implDatabaseExecServerCallSend) Send(item []*vdl.Value) error {
	return s.s.Send(item)
}

// TableClientMethods is the client interface
// containing Table methods.
//
// Table represents a collection of Rows.
// Table.Glob operates over the primary keys of Rows in the Table.
// SchemaVersion is the version number that the client expects the database
// to be at. To disable schema version checking, pass -1.
type TableClientMethods interface {
	// Create creates this Table.
	// If perms is nil, we inherit (copy) the Database perms.
	Create(ctx *context.T, schemaVersion int32, perms access.Permissions, opts ...rpc.CallOpt) error
	// Delete deletes this Table.
	Delete(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) error
	// Exists returns true only if this Table exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) (bool, error)
	// Delete deletes all rows in the given half-open range [start, limit). If
	// limit is "", all rows with keys >= start are included.
	// TODO(sadovsky): Delete prefix perms fully covered by the row range?
	DeleteRowRange(ctx *context.T, schemaVersion int32, start []byte, limit []byte, opts ...rpc.CallOpt) error
	// Scan returns all rows in the given half-open range [start, limit). If limit
	// is "", all rows with keys >= start are included. Concurrency semantics are
	// documented in model.go.
	Scan(ctx *context.T, schemaVersion int32, start []byte, limit []byte, opts ...rpc.CallOpt) (TableScanClientCall, error)
	// GetPermissions returns an array of (prefix, perms) pairs. The array is
	// sorted from longest prefix to shortest, so element zero is the one that
	// applies to the row with the given key. The last element is always the
	// prefix "" which represents the table's permissions -- the array will always
	// have at least one element.
	GetPermissions(ctx *context.T, schemaVersion int32, key string, opts ...rpc.CallOpt) ([]PrefixPermissions, error)
	// SetPermissions sets the permissions for all current and future rows with
	// the given prefix. If the prefix overlaps with an existing prefix, the
	// longest prefix that matches a row applies. For example:
	//     SetPermissions(ctx, Prefix("a/b"), perms1)
	//     SetPermissions(ctx, Prefix("a/b/c"), perms2)
	// The permissions for row "a/b/1" are perms1, and the permissions for row
	// "a/b/c/1" are perms2.
	SetPermissions(ctx *context.T, schemaVersion int32, prefix string, perms access.Permissions, opts ...rpc.CallOpt) error
	// DeletePermissions deletes the permissions for the specified prefix. Any
	// rows covered by this prefix will use the next longest prefix's permissions
	// (see the array returned by GetPermissions).
	DeletePermissions(ctx *context.T, schemaVersion int32, prefix string, opts ...rpc.CallOpt) error
}

// TableClientStub adds universal methods to TableClientMethods.
type TableClientStub interface {
	TableClientMethods
	rpc.UniversalServiceMethods
}

// TableClient returns a client stub for Table.
func TableClient(name string) TableClientStub {
	return implTableClientStub{name}
}

type implTableClientStub struct {
	name string
}

func (c implTableClientStub) Create(ctx *context.T, i0 int32, i1 access.Permissions, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Create", []interface{}{i0, i1}, nil, opts...)
	return
}

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

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

func (c implTableClientStub) DeleteRowRange(ctx *context.T, i0 int32, i1 []byte, i2 []byte, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "DeleteRowRange", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

func (c implTableClientStub) Scan(ctx *context.T, i0 int32, i1 []byte, i2 []byte, opts ...rpc.CallOpt) (ocall TableScanClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Scan", []interface{}{i0, i1, i2}, opts...); err != nil {
		return
	}
	ocall = &implTableScanClientCall{ClientCall: call}
	return
}

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

func (c implTableClientStub) SetPermissions(ctx *context.T, i0 int32, i1 string, i2 access.Permissions, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "SetPermissions", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

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

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

// TableScanClientCall represents the call returned from Table.Scan.
type TableScanClientCall interface {
	TableScanClientStream
	// 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 implTableScanClientCall struct {
	rpc.ClientCall
	valRecv KeyValue
	errRecv error
}

func (c *implTableScanClientCall) RecvStream() interface {
	Advance() bool
	Value() KeyValue
	Err() error
} {
	return implTableScanClientCallRecv{c}
}

type implTableScanClientCallRecv struct {
	c *implTableScanClientCall
}

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

// TableServerMethods is the interface a server writer
// implements for Table.
//
// Table represents a collection of Rows.
// Table.Glob operates over the primary keys of Rows in the Table.
// SchemaVersion is the version number that the client expects the database
// to be at. To disable schema version checking, pass -1.
type TableServerMethods interface {
	// Create creates this Table.
	// If perms is nil, we inherit (copy) the Database perms.
	Create(ctx *context.T, call rpc.ServerCall, schemaVersion int32, perms access.Permissions) error
	// Delete deletes this Table.
	Delete(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
	// Exists returns true only if this Table exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, call rpc.ServerCall, schemaVersion int32) (bool, error)
	// Delete deletes all rows in the given half-open range [start, limit). If
	// limit is "", all rows with keys >= start are included.
	// TODO(sadovsky): Delete prefix perms fully covered by the row range?
	DeleteRowRange(ctx *context.T, call rpc.ServerCall, schemaVersion int32, start []byte, limit []byte) error
	// Scan returns all rows in the given half-open range [start, limit). If limit
	// is "", all rows with keys >= start are included. Concurrency semantics are
	// documented in model.go.
	Scan(ctx *context.T, call TableScanServerCall, schemaVersion int32, start []byte, limit []byte) error
	// GetPermissions returns an array of (prefix, perms) pairs. The array is
	// sorted from longest prefix to shortest, so element zero is the one that
	// applies to the row with the given key. The last element is always the
	// prefix "" which represents the table's permissions -- the array will always
	// have at least one element.
	GetPermissions(ctx *context.T, call rpc.ServerCall, schemaVersion int32, key string) ([]PrefixPermissions, error)
	// SetPermissions sets the permissions for all current and future rows with
	// the given prefix. If the prefix overlaps with an existing prefix, the
	// longest prefix that matches a row applies. For example:
	//     SetPermissions(ctx, Prefix("a/b"), perms1)
	//     SetPermissions(ctx, Prefix("a/b/c"), perms2)
	// The permissions for row "a/b/1" are perms1, and the permissions for row
	// "a/b/c/1" are perms2.
	SetPermissions(ctx *context.T, call rpc.ServerCall, schemaVersion int32, prefix string, perms access.Permissions) error
	// DeletePermissions deletes the permissions for the specified prefix. Any
	// rows covered by this prefix will use the next longest prefix's permissions
	// (see the array returned by GetPermissions).
	DeletePermissions(ctx *context.T, call rpc.ServerCall, schemaVersion int32, prefix string) error
}

// TableServerStubMethods is the server interface containing
// Table methods, as expected by rpc.Server.
// The only difference between this interface and TableServerMethods
// is the streaming methods.
type TableServerStubMethods interface {
	// Create creates this Table.
	// If perms is nil, we inherit (copy) the Database perms.
	Create(ctx *context.T, call rpc.ServerCall, schemaVersion int32, perms access.Permissions) error
	// Delete deletes this Table.
	Delete(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
	// Exists returns true only if this Table exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, call rpc.ServerCall, schemaVersion int32) (bool, error)
	// Delete deletes all rows in the given half-open range [start, limit). If
	// limit is "", all rows with keys >= start are included.
	// TODO(sadovsky): Delete prefix perms fully covered by the row range?
	DeleteRowRange(ctx *context.T, call rpc.ServerCall, schemaVersion int32, start []byte, limit []byte) error
	// Scan returns all rows in the given half-open range [start, limit). If limit
	// is "", all rows with keys >= start are included. Concurrency semantics are
	// documented in model.go.
	Scan(ctx *context.T, call *TableScanServerCallStub, schemaVersion int32, start []byte, limit []byte) error
	// GetPermissions returns an array of (prefix, perms) pairs. The array is
	// sorted from longest prefix to shortest, so element zero is the one that
	// applies to the row with the given key. The last element is always the
	// prefix "" which represents the table's permissions -- the array will always
	// have at least one element.
	GetPermissions(ctx *context.T, call rpc.ServerCall, schemaVersion int32, key string) ([]PrefixPermissions, error)
	// SetPermissions sets the permissions for all current and future rows with
	// the given prefix. If the prefix overlaps with an existing prefix, the
	// longest prefix that matches a row applies. For example:
	//     SetPermissions(ctx, Prefix("a/b"), perms1)
	//     SetPermissions(ctx, Prefix("a/b/c"), perms2)
	// The permissions for row "a/b/1" are perms1, and the permissions for row
	// "a/b/c/1" are perms2.
	SetPermissions(ctx *context.T, call rpc.ServerCall, schemaVersion int32, prefix string, perms access.Permissions) error
	// DeletePermissions deletes the permissions for the specified prefix. Any
	// rows covered by this prefix will use the next longest prefix's permissions
	// (see the array returned by GetPermissions).
	DeletePermissions(ctx *context.T, call rpc.ServerCall, schemaVersion int32, prefix string) error
}

// TableServerStub adds universal methods to TableServerStubMethods.
type TableServerStub interface {
	TableServerStubMethods
	// Describe the Table interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implTableServerStub) Create(ctx *context.T, call rpc.ServerCall, i0 int32, i1 access.Permissions) error {
	return s.impl.Create(ctx, call, i0, i1)
}

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

func (s implTableServerStub) Exists(ctx *context.T, call rpc.ServerCall, i0 int32) (bool, error) {
	return s.impl.Exists(ctx, call, i0)
}

func (s implTableServerStub) DeleteRowRange(ctx *context.T, call rpc.ServerCall, i0 int32, i1 []byte, i2 []byte) error {
	return s.impl.DeleteRowRange(ctx, call, i0, i1, i2)
}

func (s implTableServerStub) Scan(ctx *context.T, call *TableScanServerCallStub, i0 int32, i1 []byte, i2 []byte) error {
	return s.impl.Scan(ctx, call, i0, i1, i2)
}

func (s implTableServerStub) GetPermissions(ctx *context.T, call rpc.ServerCall, i0 int32, i1 string) ([]PrefixPermissions, error) {
	return s.impl.GetPermissions(ctx, call, i0, i1)
}

func (s implTableServerStub) SetPermissions(ctx *context.T, call rpc.ServerCall, i0 int32, i1 string, i2 access.Permissions) error {
	return s.impl.SetPermissions(ctx, call, i0, i1, i2)
}

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

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

func (s implTableServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{TableDesc}
}

// TableDesc describes the Table interface.
var TableDesc rpc.InterfaceDesc = descTable

// descTable hides the desc to keep godoc clean.
var descTable = rpc.InterfaceDesc{
	Name:    "Table",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// Table represents a collection of Rows.\n// Table.Glob operates over the primary keys of Rows in the Table.\n// SchemaVersion is the version number that the client expects the database\n// to be at. To disable schema version checking, pass -1.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Table.\n// If perms is nil, we inherit (copy) the Database perms.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"perms", ``},         // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Table.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Table exists. Insufficient permissions\n// cause Exists to return false instead of an error.\n// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy\n// do not exist.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DeleteRowRange",
			Doc:  "// Delete deletes all rows in the given half-open range [start, limit). If\n// limit is \"\", all rows with keys >= start are included.\n// TODO(sadovsky): Delete prefix perms fully covered by the row range?",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"start", ``},         // []byte
				{"limit", ``},         // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Scan",
			Doc:  "// Scan returns all rows in the given half-open range [start, limit). If limit\n// is \"\", all rows with keys >= start are included. Concurrency semantics are\n// documented in model.go.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"start", ``},         // []byte
				{"limit", ``},         // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetPermissions",
			Doc:  "// GetPermissions returns an array of (prefix, perms) pairs. The array is\n// sorted from longest prefix to shortest, so element zero is the one that\n// applies to the row with the given key. The last element is always the\n// prefix \"\" which represents the table's permissions -- the array will always\n// have at least one element.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"key", ``},           // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []PrefixPermissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "SetPermissions",
			Doc:  "// SetPermissions sets the permissions for all current and future rows with\n// the given prefix. If the prefix overlaps with an existing prefix, the\n// longest prefix that matches a row applies. For example:\n//     SetPermissions(ctx, Prefix(\"a/b\"), perms1)\n//     SetPermissions(ctx, Prefix(\"a/b/c\"), perms2)\n// The permissions for row \"a/b/1\" are perms1, and the permissions for row\n// \"a/b/c/1\" are perms2.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"prefix", ``},        // string
				{"perms", ``},         // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "DeletePermissions",
			Doc:  "// DeletePermissions deletes the permissions for the specified prefix. Any\n// rows covered by this prefix will use the next longest prefix's permissions\n// (see the array returned by GetPermissions).",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"prefix", ``},        // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
	},
}

// TableScanServerStream is the server stream for Table.Scan.
type TableScanServerStream interface {
	// SendStream returns the send side of the Table.Scan 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 KeyValue) error
	}
}

// TableScanServerCall represents the context passed to Table.Scan.
type TableScanServerCall interface {
	rpc.ServerCall
	TableScanServerStream
}

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

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

// SendStream returns the send side of the Table.Scan server stream.
func (s *TableScanServerCallStub) SendStream() interface {
	Send(item KeyValue) error
} {
	return implTableScanServerCallSend{s}
}

type implTableScanServerCallSend struct {
	s *TableScanServerCallStub
}

func (s implTableScanServerCallSend) Send(item KeyValue) error {
	return s.s.Send(item)
}

// RowClientMethods is the client interface
// containing Row methods.
//
// Row represents a single row in a Table.
// All access checks are performed against the most specific matching prefix
// permissions in the Table.
// SchemaVersion is the version number that the client expects the database
// to be at. To disable schema version checking, pass -1.
// NOTE(sadovsky): Currently we send []byte values over the wire for Get, Put,
// and Scan. If there's a way to avoid encoding/decoding on the server side, we
// can use vdl.Value everywhere without sacrificing performance.
type RowClientMethods interface {
	// Exists returns true only if this Row exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) (bool, error)
	// Get returns the value for this Row.
	Get(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) ([]byte, error)
	// Put writes the given value for this Row.
	Put(ctx *context.T, schemaVersion int32, value []byte, opts ...rpc.CallOpt) error
	// Delete deletes this Row.
	Delete(ctx *context.T, schemaVersion int32, opts ...rpc.CallOpt) error
}

// RowClientStub adds universal methods to RowClientMethods.
type RowClientStub interface {
	RowClientMethods
	rpc.UniversalServiceMethods
}

// RowClient returns a client stub for Row.
func RowClient(name string) RowClientStub {
	return implRowClientStub{name}
}

type implRowClientStub struct {
	name string
}

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

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

func (c implRowClientStub) Put(ctx *context.T, i0 int32, i1 []byte, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Put", []interface{}{i0, i1}, nil, opts...)
	return
}

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

// RowServerMethods is the interface a server writer
// implements for Row.
//
// Row represents a single row in a Table.
// All access checks are performed against the most specific matching prefix
// permissions in the Table.
// SchemaVersion is the version number that the client expects the database
// to be at. To disable schema version checking, pass -1.
// NOTE(sadovsky): Currently we send []byte values over the wire for Get, Put,
// and Scan. If there's a way to avoid encoding/decoding on the server side, we
// can use vdl.Value everywhere without sacrificing performance.
type RowServerMethods interface {
	// Exists returns true only if this Row exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(ctx *context.T, call rpc.ServerCall, schemaVersion int32) (bool, error)
	// Get returns the value for this Row.
	Get(ctx *context.T, call rpc.ServerCall, schemaVersion int32) ([]byte, error)
	// Put writes the given value for this Row.
	Put(ctx *context.T, call rpc.ServerCall, schemaVersion int32, value []byte) error
	// Delete deletes this Row.
	Delete(ctx *context.T, call rpc.ServerCall, schemaVersion int32) error
}

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

// RowServerStub adds universal methods to RowServerStubMethods.
type RowServerStub interface {
	RowServerStubMethods
	// Describe the Row interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implRowServerStub) Exists(ctx *context.T, call rpc.ServerCall, i0 int32) (bool, error) {
	return s.impl.Exists(ctx, call, i0)
}

func (s implRowServerStub) Get(ctx *context.T, call rpc.ServerCall, i0 int32) ([]byte, error) {
	return s.impl.Get(ctx, call, i0)
}

func (s implRowServerStub) Put(ctx *context.T, call rpc.ServerCall, i0 int32, i1 []byte) error {
	return s.impl.Put(ctx, call, i0, i1)
}

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

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

func (s implRowServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{RowDesc}
}

// RowDesc describes the Row interface.
var RowDesc rpc.InterfaceDesc = descRow

// descRow hides the desc to keep godoc clean.
var descRow = rpc.InterfaceDesc{
	Name:    "Row",
	PkgPath: "v.io/syncbase/v23/services/syncbase/nosql",
	Doc:     "// Row represents a single row in a Table.\n// All access checks are performed against the most specific matching prefix\n// permissions in the Table.\n// SchemaVersion is the version number that the client expects the database\n// to be at. To disable schema version checking, pass -1.\n// NOTE(sadovsky): Currently we send []byte values over the wire for Get, Put,\n// and Scan. If there's a way to avoid encoding/decoding on the server side, we\n// can use vdl.Value everywhere without sacrificing performance.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Row exists. Insufficient permissions\n// cause Exists to return false instead of an error.\n// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy\n// do not exist.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Get",
			Doc:  "// Get returns the value for this Row.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Put",
			Doc:  "// Put writes the given value for this Row.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
				{"value", ``},         // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Row.",
			InArgs: []rpc.ArgDesc{
				{"schemaVersion", ``}, // int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}
