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

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

type implDatabaseClientStub struct {
	name string

	permissions.ObjectClientStub
}

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

// 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//  }"},
	},
	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.
	// TODO(sadovsky): Automatic GC does not interact well with sync. This API
	// needs to be revisited.
	DeleteRowRange(ctx *context.T, start string, limit string, opts ...rpc.CallOpt) 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) 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
}

// 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.
	// TODO(sadovsky): Automatic GC does not interact well with sync. This API
	// needs to be revisited.
	DeleteRowRange(ctx *context.T, call rpc.ServerCall, 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.
// There is no difference between this interface and TableServerMethods
// since there are no streaming methods.
type TableServerStubMethods TableServerMethods

// 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) 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.\n// TODO(sadovsky): Automatic GC does not interact well with sync. This API\n// needs to be revisited.",
			InArgs: []rpc.ArgDesc{
				{"start", ``}, // string
				{"limit", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			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"))},
		},
	},
}

// 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.
type RowClientMethods interface {
	// Get returns the value for this Row.
	Get(*context.T, ...rpc.CallOpt) (*vdl.Value, error)
	// Put writes the given value for this Row.
	Put(ctx *context.T, value *vdl.Value, 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 *vdl.Value, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Get", nil, []interface{}{&o0}, opts...)
	return
}

func (c implRowClientStub) Put(ctx *context.T, i0 *vdl.Value, 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.
type RowServerMethods interface {
	// Get returns the value for this Row.
	Get(*context.T, rpc.ServerCall) (*vdl.Value, error)
	// Put writes the given value for this Row.
	Put(ctx *context.T, call rpc.ServerCall, value *vdl.Value) 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) (*vdl.Value, error) {
	return s.impl.Get(ctx, call)
}

func (s implRowServerStub) Put(ctx *context.T, call rpc.ServerCall, i0 *vdl.Value) 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.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Get",
			Doc:  "// Get returns the value for this Row.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // *vdl.Value
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Put",
			Doc:  "// Put writes the given value for this Row.",
			InArgs: []rpc.ArgDesc{
				{"value", ``}, // *vdl.Value
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Row.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}
