// 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")
)

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")
}

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

// DatabaseWatcherClientMethods is the client interface
// containing DatabaseWatcher methods.
//
// Watch 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.
//
// 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.
//
// Watch 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.
//
// 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:     "// Watch allows a client to watch for updates in the database. For each watched\n// request, the client will receive a reliable stream of watch events without\n// re-ordering. See watch.GlobWatcher for a detailed explanation of the\n// behavior.\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.
	//
	// 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() FetchStatus
		// 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 FetchStatus
	errRecv error
}

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

type implBlobManagerFetchBlobClientCallRecv struct {
	c *implBlobManagerFetchBlobClientCall
}

func (c implBlobManagerFetchBlobClientCallRecv) Advance() bool {
	c.c.valRecv = FetchStatus{}
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implBlobManagerFetchBlobClientCallRecv) Value() FetchStatus {
	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.
	//
	// 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.
	//
	// 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.\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 FetchStatus) 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 FetchStatus) error
} {
	return implBlobManagerFetchBlobServerCallSend{s}
}

type implBlobManagerFetchBlobServerCallSend struct {
	s *BlobManagerFetchBlobServerCallStub
}

func (s implBlobManagerFetchBlobServerCallSend) Send(item FetchStatus) 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"))},
		},
	},
}

// 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.
//
// 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
	// Watch 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.
	//
	// 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
	// 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, perms access.Permissions, metadata *SchemaMetadata, opts ...rpc.CallOpt) error
	// Delete deletes this Database.
	Delete(*context.T, ...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(*context.T, ...rpc.CallOpt) (bool, 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, 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(*context.T, ...rpc.CallOpt) 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, query string, opts ...rpc.CallOpt) (DatabaseExecClientCall, 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(*context.T, ...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)}
}

type implDatabaseClientStub struct {
	name string

	permissions.ObjectClientStub
	DatabaseWatcherClientStub
	SyncGroupManagerClientStub
	BlobManagerClientStub
	SchemaManagerClientStub
}

func (c implDatabaseClientStub) Create(ctx *context.T, i0 access.Permissions, i1 *SchemaMetadata, 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, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Delete", nil, nil, opts...)
	return
}

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

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

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

func (c implDatabaseClientStub) Exec(ctx *context.T, i0 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}, opts...); err != nil {
		return
	}
	ocall = &implDatabaseExecClientCall{ClientCall: call}
	return
}

func (c implDatabaseClientStub) Abort(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Abort", nil, 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.
//
// 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
	// Watch 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.
	//
	// 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
	// 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, perms access.Permissions, metadata *SchemaMetadata) error
	// Delete deletes this Database.
	Delete(*context.T, rpc.ServerCall) 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(*context.T, rpc.ServerCall) (bool, 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, 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(*context.T, rpc.ServerCall) 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, query string) 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(*context.T, rpc.ServerCall) 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
	// Watch 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.
	//
	// 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
	// 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, perms access.Permissions, metadata *SchemaMetadata) error
	// Delete deletes this Database.
	Delete(*context.T, rpc.ServerCall) 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(*context.T, rpc.ServerCall) (bool, 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, 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(*context.T, rpc.ServerCall) 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, query string) 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(*context.T, rpc.ServerCall) 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),
	}
	// 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
	gs *rpc.GlobState
}

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

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

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

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

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

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

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

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

// 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//\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", "// Watch allows a client to watch for updates in the database. For each watched\n// request, the client will receive a reliable stream of watch events without\n// re-ordering. See watch.GlobWatcher for a detailed explanation of the\n// behavior.\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."},
	},
	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{
				{"perms", ``},    // access.Permissions
				{"metadata", ``}, // *SchemaMetadata
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Database.",
			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.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			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{
				{"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.",
			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{
				{"query", ``}, // string
			},
			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.",
			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.
type TableClientMethods interface {
	// Create creates this Table.
	// If perms is nil, we inherit (copy) the Database perms.
	Create(ctx *context.T, perms access.Permissions, opts ...rpc.CallOpt) error
	// Delete deletes this Table.
	Delete(*context.T, ...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(*context.T, ...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.
	DeleteRowRange(ctx *context.T, 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, 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, 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, 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, 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 access.Permissions, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Create", []interface{}{i0}, nil, opts...)
	return
}

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

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

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

func (c implTableClientStub) Scan(ctx *context.T, i0 []byte, i1 []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}, opts...); err != nil {
		return
	}
	ocall = &implTableScanClientCall{ClientCall: call}
	return
}

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

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

func (c implTableClientStub) DeletePermissions(ctx *context.T, i0 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "DeletePermissions", []interface{}{i0}, 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.
type TableServerMethods interface {
	// Create creates this Table.
	// If perms is nil, we inherit (copy) the Database perms.
	Create(ctx *context.T, call rpc.ServerCall, perms access.Permissions) error
	// Delete deletes this Table.
	Delete(*context.T, rpc.ServerCall) 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(*context.T, rpc.ServerCall) (bool, error)
	// Delete deletes all rows in the given half-open range [start, limit). If
	// limit is "", all rows with keys >= start are included.
	DeleteRowRange(ctx *context.T, call rpc.ServerCall, 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, 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, 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, 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, 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, perms access.Permissions) error
	// Delete deletes this Table.
	Delete(*context.T, rpc.ServerCall) 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(*context.T, rpc.ServerCall) (bool, error)
	// Delete deletes all rows in the given half-open range [start, limit). If
	// limit is "", all rows with keys >= start are included.
	DeleteRowRange(ctx *context.T, call rpc.ServerCall, 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, 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, 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, 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, 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 access.Permissions) error {
	return s.impl.Create(ctx, call, i0)
}

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

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

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

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

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

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

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

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.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Table.\n// If perms is nil, we inherit (copy) the Database perms.",
			InArgs: []rpc.ArgDesc{
				{"perms", ``}, // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Table.",
			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.",
			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.",
			InArgs: []rpc.ArgDesc{
				{"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{
				{"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{
				{"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{
				{"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{
				{"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.
// 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(*context.T, ...rpc.CallOpt) (bool, error)
	// Get returns the value for this Row.
	Get(*context.T, ...rpc.CallOpt) ([]byte, error)
	// Put writes the given value for this Row.
	Put(ctx *context.T, value []byte, opts ...rpc.CallOpt) error
	// Delete deletes this Row.
	Delete(*context.T, ...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, opts ...rpc.CallOpt) (o0 bool, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Exists", nil, []interface{}{&o0}, opts...)
	return
}

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

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

func (c implRowClientStub) Delete(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Delete", nil, 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.
// 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(*context.T, rpc.ServerCall) (bool, error)
	// Get returns the value for this Row.
	Get(*context.T, rpc.ServerCall) ([]byte, error)
	// Put writes the given value for this Row.
	Put(ctx *context.T, call rpc.ServerCall, value []byte) error
	// Delete deletes this Row.
	Delete(*context.T, rpc.ServerCall) 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) (bool, error) {
	return s.impl.Exists(ctx, call)
}

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

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

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

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// 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.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Get",
			Doc:  "// Get returns the value for this Row.",
			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{
				{"value", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Row.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}
