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

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

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

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

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

// 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
	// SyncGroupManager is the interface for SyncGroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncGroupManagerClientMethods
	// 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, opts ...rpc.CallOpt) error
	// Delete deletes this Database.
	Delete(*context.T, ...rpc.CallOpt) 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.
	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
	// 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), SyncGroupManagerClient(name)}
}

type implDatabaseClientStub struct {
	name string

	permissions.ObjectClientStub
	SyncGroupManagerClientStub
}

func (c implDatabaseClientStub) 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 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) 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) Abort(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Abort", nil, nil, opts...)
	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
	// SyncGroupManager is the interface for SyncGroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncGroupManagerServerMethods
	// 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) error
	// Delete deletes this Database.
	Delete(*context.T, rpc.ServerCall) 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.
	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
	// 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.
// There is no difference between this interface and DatabaseServerMethods
// since there are no streaming methods.
type DatabaseServerStubMethods DatabaseServerMethods

// 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),
		SyncGroupManagerServerStub: SyncGroupManagerServer(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
	SyncGroupManagerServerStub
	gs *rpc.GlobState
}

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

func (s implDatabaseServerStub) Delete(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.Delete(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) 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, SyncGroupManagerDesc}
}

// 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//  }"},
		{"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."},
	},
	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
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Database.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			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.\n//\n// Concurrency semantics are documented in model.go.",
			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: "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"))},
		},
	},
}

// 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
	// DeleteRowRange deletes all rows in the given range. If the last row that is
	// covered by a prefix from SetPermissions is deleted, that (prefix, perms)
	// pair is removed. If limit is "", all rows with keys >= start are included.
	// TODO(sadovsky): Automatic GC interacts poorly with sync. Revisit this API.
	DeleteRowRange(ctx *context.T, start string, limit string, opts ...rpc.CallOpt) error
	// Scan returns all rows in the given range. The returned stream reads from a
	// consistent snapshot taken at the time of the Scan RPC. If limit is "", all
	// rows with keys >= start are included.
	Scan(ctx *context.T, start string, limit string, opts ...rpc.CallOpt) (TableScanClientCall, 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 will fail if called with a prefix that does not match any
	// rows.
	SetPermissions(ctx *context.T, prefix string, perms access.Permissions, opts ...rpc.CallOpt) 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)
	// 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) DeleteRowRange(ctx *context.T, i0 string, i1 string, 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 string, i1 string, 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) 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) 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) 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
	// DeleteRowRange deletes all rows in the given range. If the last row that is
	// covered by a prefix from SetPermissions is deleted, that (prefix, perms)
	// pair is removed. If limit is "", all rows with keys >= start are included.
	// TODO(sadovsky): Automatic GC interacts poorly with sync. Revisit this API.
	DeleteRowRange(ctx *context.T, call rpc.ServerCall, start string, limit string) error
	// Scan returns all rows in the given range. The returned stream reads from a
	// consistent snapshot taken at the time of the Scan RPC. If limit is "", all
	// rows with keys >= start are included.
	Scan(ctx *context.T, call TableScanServerCall, start string, limit string) 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 will fail if called with a prefix that does not match any
	// rows.
	SetPermissions(ctx *context.T, call rpc.ServerCall, prefix string, perms access.Permissions) 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)
	// 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
	// DeleteRowRange deletes all rows in the given range. If the last row that is
	// covered by a prefix from SetPermissions is deleted, that (prefix, perms)
	// pair is removed. If limit is "", all rows with keys >= start are included.
	// TODO(sadovsky): Automatic GC interacts poorly with sync. Revisit this API.
	DeleteRowRange(ctx *context.T, call rpc.ServerCall, start string, limit string) error
	// Scan returns all rows in the given range. The returned stream reads from a
	// consistent snapshot taken at the time of the Scan RPC. If limit is "", all
	// rows with keys >= start are included.
	Scan(ctx *context.T, call *TableScanServerCallStub, start string, limit string) 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 will fail if called with a prefix that does not match any
	// rows.
	SetPermissions(ctx *context.T, call rpc.ServerCall, prefix string, perms access.Permissions) 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)
	// 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) DeleteRowRange(ctx *context.T, call rpc.ServerCall, i0 string, i1 string) error {
	return s.impl.DeleteRowRange(ctx, call, i0, i1)
}

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

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) GetPermissions(ctx *context.T, call rpc.ServerCall, i0 string) ([]PrefixPermissions, error) {
	return s.impl.GetPermissions(ctx, call, i0)
}

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: "DeleteRowRange",
			Doc:  "// DeleteRowRange deletes all rows in the given range. If the last row that is\n// covered by a prefix from SetPermissions is deleted, that (prefix, perms)\n// pair is removed. If limit is \"\", all rows with keys >= start are included.\n// TODO(sadovsky): Automatic GC interacts poorly with sync. Revisit this API.",
			InArgs: []rpc.ArgDesc{
				{"start", ``}, // string
				{"limit", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Scan",
			Doc:  "// Scan returns all rows in the given range. The returned stream reads from a\n// consistent snapshot taken at the time of the Scan RPC. If limit is \"\", all\n// rows with keys >= start are included.",
			InArgs: []rpc.ArgDesc{
				{"start", ``}, // string
				{"limit", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			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.\n//\n// SetPermissions will fail if called with a prefix that does not match any\n// rows.",
			InArgs: []rpc.ArgDesc{
				{"prefix", ``}, // string
				{"perms", ``},  // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			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: "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 {
	// 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) 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 {
	// 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) 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: "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"))},
		},
	},
}
