// 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.
// Package: syncbase

// Package syncbase defines the wire API for a structured store that supports
// peer-to-peer synchronization.
//
// TODO(sadovsky): Write a detailed package description, or provide a reference
// to the Syncbase documentation.
//
// Security notes:
// The Syncbase service uses permissions tags from v23/security/access.Tag,
// restricted on each hierarchy level to tags used at that level:
// - Valid Service permissions tags are all v23/security/access.Tag tags.
// - Valid Database permissions tags are Admin, Read, Write, Resolve.
// - Valid Collection permissions tags are Admin, Read, Write.
// - Valid Syncgroup permissions tags are Admin, Read.
// Other tags are not allowed and are reserved for future use.
// Unless stated otherwise, each permissions tag requirement on a method also
// implies requiring Resolve on all levels of hierarchy up to, but excluding,
// the level requiring the tag.
// ErrNoAccess, Err[No]Exist, ErrUnknownBatch are only returned if the caller
// is allowed to call Exists on the receiver of the RPC (or the first missing
// component of the hierarchy to the receiver); otherwise, the returned error
// is ErrNoExistOrNoAccess.
package syncbase

import (
	"fmt"
	"io"
	"time"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/services/permissions"
	"v.io/v23/services/watch"
	"v.io/v23/vdl"
	vdltime "v.io/v23/vdlroot/time"
	"v.io/v23/verror"
	"v.io/v23/vom"
)

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

//////////////////////////////////////////////////
// Type definitions

// Id is a {blessing, name} pair, used to identify a database or a collection.
type Id struct {
	Blessing string
	Name     string
}

func (Id) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.Id"`
}) {
}

func (x Id) VDLIsZero() bool {
	return x == Id{}
}

func (x Id) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.Blessing != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Blessing); err != nil {
			return err
		}
	}
	if x.Name != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.Name); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Id) VDLRead(dec vdl.Decoder) error {
	*x = Id{}
	if err := dec.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_1 {
			index = __VDLType_struct_1.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Blessing = value
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Name = value
			}
		}
	}
}

// DevModeUpdateVClockOpts specifies what DevModeUpdateVClock should do, as
// described below.
type DevModeUpdateVClockOpts struct {
	// If specified, sets the NTP host to talk to for subsequent NTP requests.
	NtpHost string
	// If Now is specified, the fake system clock is updated to the given values
	// of Now and ElapsedTime. If Now is not specified (i.e. takes the zero
	// value), the system clock is not touched by DevModeUpdateVClock.
	Now         time.Time
	ElapsedTime time.Duration
	// If specified, the clock daemon's local and/or NTP update code is triggered
	// after applying the updates specified by the fields above. (Helpful because
	// otherwise these only run periodically.) These functions work even if the
	// clock daemon hasn't been started.
	DoNtpUpdate   bool
	DoLocalUpdate bool
}

func (DevModeUpdateVClockOpts) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.DevModeUpdateVClockOpts"`
}) {
}

func (x DevModeUpdateVClockOpts) VDLIsZero() bool {
	if x.NtpHost != "" {
		return false
	}
	if !x.Now.IsZero() {
		return false
	}
	if x.ElapsedTime != 0 {
		return false
	}
	if x.DoNtpUpdate {
		return false
	}
	if x.DoLocalUpdate {
		return false
	}
	return true
}

func (x DevModeUpdateVClockOpts) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	if x.NtpHost != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.NtpHost); err != nil {
			return err
		}
	}
	if !x.Now.IsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.Now); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.ElapsedTime != 0 {
		if err := enc.NextField(2); err != nil {
			return err
		}
		var wire vdltime.Duration
		if err := vdltime.DurationFromNative(&wire, x.ElapsedTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.DoNtpUpdate {
		if err := enc.NextFieldValueBool(3, vdl.BoolType, x.DoNtpUpdate); err != nil {
			return err
		}
	}
	if x.DoLocalUpdate {
		if err := enc.NextFieldValueBool(4, vdl.BoolType, x.DoLocalUpdate); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *DevModeUpdateVClockOpts) VDLRead(dec vdl.Decoder) error {
	*x = DevModeUpdateVClockOpts{}
	if err := dec.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_2 {
			index = __VDLType_struct_2.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.NtpHost = value
			}
		case 1:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.Now); err != nil {
				return err
			}
		case 2:
			var wire vdltime.Duration
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.DurationToNative(wire, &x.ElapsedTime); err != nil {
				return err
			}
		case 3:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.DoNtpUpdate = value
			}
		case 4:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.DoLocalUpdate = value
			}
		}
	}
}

// BatchOptions configures a batch.
// TODO(sadovsky): Add more options, e.g. to configure isolation, timeouts,
// whether to track the read set and/or write set, etc.
// TODO(sadovsky): Maybe add a DefaultBatchOptions() function that initializes
// BatchOptions with our desired defaults. Clients would be encouraged to
// initialize their BatchOptions object using that function and then modify it
// to their liking.
type BatchOptions struct {
	// Arbitrary string, typically used to describe the intent behind a batch.
	// Hints are surfaced to clients during conflict resolution.
	// TODO(sadovsky): Use "any" here?
	Hint string
	// ReadOnly specifies whether the batch should allow writes.
	// If ReadOnly is set to true, Abort() should be used to release any resources
	// associated with this batch (though it is not strictly required), and
	// Commit() will always fail.
	ReadOnly bool
}

func (BatchOptions) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.BatchOptions"`
}) {
}

func (x BatchOptions) VDLIsZero() bool {
	return x == BatchOptions{}
}

func (x BatchOptions) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_5); err != nil {
		return err
	}
	if x.Hint != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Hint); err != nil {
			return err
		}
	}
	if x.ReadOnly {
		if err := enc.NextFieldValueBool(1, vdl.BoolType, x.ReadOnly); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BatchOptions) VDLRead(dec vdl.Decoder) error {
	*x = BatchOptions{}
	if err := dec.StartValue(__VDLType_struct_5); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_5 {
			index = __VDLType_struct_5.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Hint = value
			}
		case 1:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.ReadOnly = value
			}
		}
	}
}

// BatchHandle is a reference to a batch.
type BatchHandle string

func (BatchHandle) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.BatchHandle"`
}) {
}

func (x BatchHandle) VDLIsZero() bool {
	return x == ""
}

func (x BatchHandle) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_string_6, string(x)); err != nil {
		return err
	}
	return nil
}

func (x *BatchHandle) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		*x = BatchHandle(value)
	}
	return nil
}

// KeyValue is a key-value pair.
type KeyValue struct {
	Key   string
	Value *vom.RawBytes
}

func (KeyValue) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.KeyValue"`
}) {
}

func (x KeyValue) VDLIsZero() bool {
	if x.Key != "" {
		return false
	}
	if x.Value != nil && !x.Value.VDLIsZero() {
		return false
	}
	return true
}

func (x KeyValue) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_7); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Key); err != nil {
			return err
		}
	}
	if x.Value != nil && !x.Value.VDLIsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.Value.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *KeyValue) VDLRead(dec vdl.Decoder) error {
	*x = KeyValue{
		Value: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
	}
	if err := dec.StartValue(__VDLType_struct_7); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_7 {
			index = __VDLType_struct_7.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Key = value
			}
		case 1:
			x.Value = new(vom.RawBytes)
			if err := x.Value.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

// SyncgroupSpec contains the specification for a syncgroup.
type SyncgroupSpec struct {
	// Human-readable description of this syncgroup.
	Description string
	// Optional. If present, any syncbase that is the admin of this syncgroup
	// is responsible for ensuring that the syncgroup is published to this
	// syncbase instance.
	PublishSyncbaseName string
	// Permissions governing access to this syncgroup. Must include at least one
	// admin.
	Perms access.Permissions
	// Data (set of collectionIds) covered by this syncgroup.
	Collections []Id
	// Mount tables at which to advertise this syncgroup, for rendezvous purposes.
	// (Note that in addition to these mount tables, Syncbase also uses
	// network-neighborhood-based discovery for rendezvous.)
	// We expect most clients to specify a single mount table, but we accept an
	// array of mount tables to permit the mount table to be changed over time
	// without disruption.
	// TODO(hpucha): Figure out a convention for advertising syncgroups in the
	// mount table.
	MountTables []string
	// Specifies the privacy of this syncgroup. More specifically, specifies
	// whether blobs in this syncgroup can be served to clients presenting
	// blobrefs obtained from other syncgroups.
	IsPrivate bool
}

func (SyncgroupSpec) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.SyncgroupSpec"`
}) {
}

func (x SyncgroupSpec) VDLIsZero() bool {
	if x.Description != "" {
		return false
	}
	if x.PublishSyncbaseName != "" {
		return false
	}
	if len(x.Perms) != 0 {
		return false
	}
	if len(x.Collections) != 0 {
		return false
	}
	if len(x.MountTables) != 0 {
		return false
	}
	if x.IsPrivate {
		return false
	}
	return true
}

func (x SyncgroupSpec) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	if x.Description != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Description); err != nil {
			return err
		}
	}
	if x.PublishSyncbaseName != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.PublishSyncbaseName); err != nil {
			return err
		}
	}
	if len(x.Perms) != 0 {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := x.Perms.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.Collections) != 0 {
		if err := enc.NextField(3); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Collections); err != nil {
			return err
		}
	}
	if len(x.MountTables) != 0 {
		if err := enc.NextField(4); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.MountTables); err != nil {
			return err
		}
	}
	if x.IsPrivate {
		if err := enc.NextFieldValueBool(5, vdl.BoolType, x.IsPrivate); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []Id) error {
	if err := enc.StartValue(__VDLType_list_10); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_2(enc vdl.Encoder, x []string) error {
	if err := enc.StartValue(__VDLType_list_11); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SyncgroupSpec) VDLRead(dec vdl.Decoder) error {
	*x = SyncgroupSpec{}
	if err := dec.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_8 {
			index = __VDLType_struct_8.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Description = value
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.PublishSyncbaseName = value
			}
		case 2:
			if err := x.Perms.VDLRead(dec); err != nil {
				return err
			}
		case 3:
			if err := __VDLReadAnon_list_1(dec, &x.Collections); err != nil {
				return err
			}
		case 4:
			if err := __VDLReadAnon_list_2(dec, &x.MountTables); err != nil {
				return err
			}
		case 5:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.IsPrivate = value
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]Id) error {
	if err := dec.StartValue(__VDLType_list_10); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]Id, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem Id
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			*x = append(*x, elem)
		}
	}
}

func __VDLReadAnon_list_2(dec vdl.Decoder, x *[]string) error {
	if err := dec.StartValue(__VDLType_list_11); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]string, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, elem, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			*x = append(*x, elem)
		}
	}
}

// SyncgroupMemberInfo contains per-member metadata.
type SyncgroupMemberInfo struct {
	SyncPriority byte
	BlobDevType  byte // See BlobDevType* constants.
}

func (SyncgroupMemberInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.SyncgroupMemberInfo"`
}) {
}

func (x SyncgroupMemberInfo) VDLIsZero() bool {
	return x == SyncgroupMemberInfo{}
}

func (x SyncgroupMemberInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_12); err != nil {
		return err
	}
	if x.SyncPriority != 0 {
		if err := enc.NextFieldValueUint(0, vdl.ByteType, uint64(x.SyncPriority)); err != nil {
			return err
		}
	}
	if x.BlobDevType != 0 {
		if err := enc.NextFieldValueUint(1, vdl.ByteType, uint64(x.BlobDevType)); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SyncgroupMemberInfo) VDLRead(dec vdl.Decoder) error {
	*x = SyncgroupMemberInfo{}
	if err := dec.StartValue(__VDLType_struct_12); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_12 {
			index = __VDLType_struct_12.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.SyncPriority = byte(value)
			}
		case 1:
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.BlobDevType = byte(value)
			}
		}
	}
}

// ResolverType defines the possible conflict resolution policies.
// A Conflict is defined as presence of two independent sets of updates
// originating from the same version of an object. Syncbase
// uses version vectors to determine sequence of changes to a given row. Hence
// if device A updates a row with key "foo" from version V3 to V4, then syncs
// with device B which further updates the same row from version V4 to V5 and
// then V5 is synced back to device A, device A will see V5 as a forward
// progression of "foo" and not a conflict with V3 of "foo". But in the
// meantime if device A had already updated "foo" again from version V4 to
// version V6 then there is a conflict between V5 and V6 with V4 being the
// common ancestor.
type ResolverType int

const (
	ResolverTypeLastWins ResolverType = iota
	ResolverTypeAppResolves
	ResolverTypeDefer
)

// ResolverTypeAll holds all labels for ResolverType.
var ResolverTypeAll = [...]ResolverType{ResolverTypeLastWins, ResolverTypeAppResolves, ResolverTypeDefer}

// ResolverTypeFromString creates a ResolverType from a string label.
func ResolverTypeFromString(label string) (x ResolverType, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *ResolverType) Set(label string) error {
	switch label {
	case "LastWins", "lastwins":
		*x = ResolverTypeLastWins
		return nil
	case "AppResolves", "appresolves":
		*x = ResolverTypeAppResolves
		return nil
	case "Defer", "defer":
		*x = ResolverTypeDefer
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in syncbase.ResolverType", label)
}

// String returns the string label of x.
func (x ResolverType) String() string {
	switch x {
	case ResolverTypeLastWins:
		return "LastWins"
	case ResolverTypeAppResolves:
		return "AppResolves"
	case ResolverTypeDefer:
		return "Defer"
	}
	return ""
}

func (ResolverType) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.ResolverType"`
	Enum struct{ LastWins, AppResolves, Defer string }
}) {
}

func (x ResolverType) VDLIsZero() bool {
	return x == ResolverTypeLastWins
}

func (x ResolverType) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_enum_13, x.String()); err != nil {
		return err
	}
	return nil
}

func (x *ResolverType) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

// BatchSource represents where the batch was committed.
type BatchSource int

const (
	BatchSourceLocal BatchSource = iota
	BatchSourceRemote
)

// BatchSourceAll holds all labels for BatchSource.
var BatchSourceAll = [...]BatchSource{BatchSourceLocal, BatchSourceRemote}

// BatchSourceFromString creates a BatchSource from a string label.
func BatchSourceFromString(label string) (x BatchSource, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *BatchSource) Set(label string) error {
	switch label {
	case "Local", "local":
		*x = BatchSourceLocal
		return nil
	case "Remote", "remote":
		*x = BatchSourceRemote
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in syncbase.BatchSource", label)
}

// String returns the string label of x.
func (x BatchSource) String() string {
	switch x {
	case BatchSourceLocal:
		return "Local"
	case BatchSourceRemote:
		return "Remote"
	}
	return ""
}

func (BatchSource) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.BatchSource"`
	Enum struct{ Local, Remote string }
}) {
}

func (x BatchSource) VDLIsZero() bool {
	return x == BatchSourceLocal
}

func (x BatchSource) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_enum_14, x.String()); err != nil {
		return err
	}
	return nil
}

func (x *BatchSource) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

type BatchInfo struct {
	// Id is an identifier for a batch contained in a conflict. It is
	// unique only in the context of a given conflict. Its purpose is solely to
	// group one or more RowInfo objects together to represent a batch that
	// was committed by the client.
	Id uint64
	// Hint is the hint provided by the client when this batch was committed.
	Hint string
	// Source states where the batch comes from.
	Source BatchSource
}

func (BatchInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.BatchInfo"`
}) {
}

func (x BatchInfo) VDLIsZero() bool {
	return x == BatchInfo{}
}

func (x BatchInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_15); err != nil {
		return err
	}
	if x.Id != 0 {
		if err := enc.NextFieldValueUint(0, vdl.Uint64Type, x.Id); err != nil {
			return err
		}
	}
	if x.Hint != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.Hint); err != nil {
			return err
		}
	}
	if x.Source != BatchSourceLocal {
		if err := enc.NextFieldValueString(2, __VDLType_enum_14, x.Source.String()); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BatchInfo) VDLRead(dec vdl.Decoder) error {
	*x = BatchInfo{}
	if err := dec.StartValue(__VDLType_struct_15); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_15 {
			index = __VDLType_struct_15.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Id = value
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Hint = value
			}
		case 2:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.Source.Set(value); err != nil {
					return err
				}
			}
		}
	}
}

// ValueState represents the state for Value object providing information about
// whether the Value object's Byte field is empty or not.
type ValueState int

const (
	ValueStateExists ValueState = iota
	ValueStateNoExists
	ValueStateDeleted
	ValueStateUnknown
)

// ValueStateAll holds all labels for ValueState.
var ValueStateAll = [...]ValueState{ValueStateExists, ValueStateNoExists, ValueStateDeleted, ValueStateUnknown}

// ValueStateFromString creates a ValueState from a string label.
func ValueStateFromString(label string) (x ValueState, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *ValueState) Set(label string) error {
	switch label {
	case "Exists", "exists":
		*x = ValueStateExists
		return nil
	case "NoExists", "noexists":
		*x = ValueStateNoExists
		return nil
	case "Deleted", "deleted":
		*x = ValueStateDeleted
		return nil
	case "Unknown", "unknown":
		*x = ValueStateUnknown
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in syncbase.ValueState", label)
}

// String returns the string label of x.
func (x ValueState) String() string {
	switch x {
	case ValueStateExists:
		return "Exists"
	case ValueStateNoExists:
		return "NoExists"
	case ValueStateDeleted:
		return "Deleted"
	case ValueStateUnknown:
		return "Unknown"
	}
	return ""
}

func (ValueState) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.ValueState"`
	Enum struct{ Exists, NoExists, Deleted, Unknown string }
}) {
}

func (x ValueState) VDLIsZero() bool {
	return x == ValueStateExists
}

func (x ValueState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_enum_16, x.String()); err != nil {
		return err
	}
	return nil
}

func (x *ValueState) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

// Value contains the encoded bytes for a row's value stored in syncbase.
type Value struct {
	// State provides information about whether the field Bytes is empty or
	// not and if it is empty then why.
	State ValueState
	// VOM encoded bytes for a row's value or nil if the row was deleted.
	Bytes *vom.RawBytes
	// Write timestamp for this value
	WriteTs time.Time
}

func (Value) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.Value"`
}) {
}

func (x Value) VDLIsZero() bool {
	if x.State != ValueStateExists {
		return false
	}
	if x.Bytes != nil && !x.Bytes.VDLIsZero() {
		return false
	}
	if !x.WriteTs.IsZero() {
		return false
	}
	return true
}

func (x Value) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_17); err != nil {
		return err
	}
	if x.State != ValueStateExists {
		if err := enc.NextFieldValueString(0, __VDLType_enum_16, x.State.String()); err != nil {
			return err
		}
	}
	if x.Bytes != nil && !x.Bytes.VDLIsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.Bytes.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.WriteTs.IsZero() {
		if err := enc.NextField(2); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.WriteTs); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Value) VDLRead(dec vdl.Decoder) error {
	*x = Value{
		Bytes: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
	}
	if err := dec.StartValue(__VDLType_struct_17); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_17 {
			index = __VDLType_struct_17.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.State.Set(value); err != nil {
					return err
				}
			}
		case 1:
			x.Bytes = new(vom.RawBytes)
			if err := x.Bytes.VDLRead(dec); err != nil {
				return err
			}
		case 2:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.WriteTs); err != nil {
				return err
			}
		}
	}
}

// RowOp represents a read or write operation on a row corresponding to the
// given key.
type RowOp struct {
	// The key under conflict.
	Key string
	// LocalValue contains the value read or written by local syncbase or nil.
	LocalValue *Value
	// RemoteValue contains the value read or written by remote syncbase or nil.
	RemoteValue *Value
	// AncestorValue contains the value for the key which is the lowest common
	// ancestor of the two values represented by LocalValue and RemoteValue or
	// nil if no ancestor exists or if the operation was read.
	AncestorValue *Value
}

func (RowOp) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.RowOp"`
}) {
}

func (x RowOp) VDLIsZero() bool {
	return x == RowOp{}
}

func (x RowOp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_18); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Key); err != nil {
			return err
		}
	}
	if x.LocalValue != nil {
		if err := enc.NextField(1); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := x.LocalValue.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.RemoteValue != nil {
		if err := enc.NextField(2); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := x.RemoteValue.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.AncestorValue != nil {
		if err := enc.NextField(3); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := x.AncestorValue.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *RowOp) VDLRead(dec vdl.Decoder) error {
	*x = RowOp{}
	if err := dec.StartValue(__VDLType_struct_18); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_18 {
			index = __VDLType_struct_18.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Key = value
			}
		case 1:
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.LocalValue = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.LocalValue = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.LocalValue.VDLRead(dec); err != nil {
					return err
				}
			}
		case 2:
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.RemoteValue = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.RemoteValue = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.RemoteValue.VDLRead(dec); err != nil {
					return err
				}
			}
		case 3:
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.AncestorValue = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.AncestorValue = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.AncestorValue.VDLRead(dec); err != nil {
					return err
				}
			}
		}
	}
}

// ScanOp provides details of a scan operation.
type ScanOp struct {
	// Start contains the starting key for a range scan.
	Start string
	// Limit contains the end key for a range scan.
	Limit string
}

func (ScanOp) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.ScanOp"`
}) {
}

func (x ScanOp) VDLIsZero() bool {
	return x == ScanOp{}
}

func (x ScanOp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_20); err != nil {
		return err
	}
	if x.Start != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Start); err != nil {
			return err
		}
	}
	if x.Limit != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.Limit); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ScanOp) VDLRead(dec vdl.Decoder) error {
	*x = ScanOp{}
	if err := dec.StartValue(__VDLType_struct_20); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_20 {
			index = __VDLType_struct_20.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Start = value
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Limit = value
			}
		}
	}
}

type (
	// Operation represents any single field of the Operation union type.
	//
	// Operation represents a specific operation on a row or a set of rows that is
	// a part of the conflict.
	Operation interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the Operation union type.
		__VDLReflect(__OperationReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// OperationRead represents field Read of the Operation union type.
	//
	// Read represents a read operation performed on a specific row. For a given
	// row key there can only be at max one Read operation within a conflict.
	OperationRead struct{ Value RowOp }
	// OperationWrite represents field Write of the Operation union type.
	//
	// Write represents a write operation performed on a specific row. For a
	// given row key there can only be at max one Write operation within a
	// conflict.
	OperationWrite struct{ Value RowOp }
	// OperationScan represents field Scan of the Operation union type.
	//
	// Scan represents a scan operation performed over a specific range of keys.
	// For a given key range there can be at max one ScanOp within the Conflict.
	OperationScan struct{ Value ScanOp }
	// __OperationReflect describes the Operation union type.
	__OperationReflect struct {
		Name  string `vdl:"v.io/v23/services/syncbase.Operation"`
		Type  Operation
		Union struct {
			Read  OperationRead
			Write OperationWrite
			Scan  OperationScan
		}
	}
)

func (x OperationRead) Index() int                      { return 0 }
func (x OperationRead) Interface() interface{}          { return x.Value }
func (x OperationRead) Name() string                    { return "Read" }
func (x OperationRead) __VDLReflect(__OperationReflect) {}

func (x OperationWrite) Index() int                      { return 1 }
func (x OperationWrite) Interface() interface{}          { return x.Value }
func (x OperationWrite) Name() string                    { return "Write" }
func (x OperationWrite) __VDLReflect(__OperationReflect) {}

func (x OperationScan) Index() int                      { return 2 }
func (x OperationScan) Interface() interface{}          { return x.Value }
func (x OperationScan) Name() string                    { return "Scan" }
func (x OperationScan) __VDLReflect(__OperationReflect) {}

func (x OperationRead) VDLIsZero() bool {
	return x.Value == RowOp{}
}

func (x OperationWrite) VDLIsZero() bool {
	return false
}

func (x OperationScan) VDLIsZero() bool {
	return false
}

func (x OperationRead) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_21); err != nil {
		return err
	}
	if err := enc.NextField(0); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x OperationWrite) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_21); err != nil {
		return err
	}
	if err := enc.NextField(1); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x OperationScan) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_21); err != nil {
		return err
	}
	if err := enc.NextField(2); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadOperation(dec vdl.Decoder, x *Operation) error {
	if err := dec.StartValue(__VDLType_union_21); err != nil {
		return err
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_21 {
		name := decType.Field(index).Name
		index = __VDLType_union_21.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field OperationRead
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case 1:
		var field OperationWrite
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case 2:
		var field OperationScan
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, x, dec.Type())
	}
	return dec.FinishValue()
}

// RowInfo contains a single operation performed on a row (in case of read or
// write) or a range or rows (in case of scan) along with a mapping to each
// of the batches that this operation belongs to.
// For example, if Row1 was updated on local syncbase conflicting with a write
// on remote syncbase as part of two separate batches, then it will be
// represented by a single RowInfo with Write Operation containing the
// respective local and remote values along with the batch id for both batches
// stored in the BatchIds field.
type RowInfo struct {
	// Op is a specific operation represented by RowInfo
	Op Operation
	// BatchIds contains ids of all batches that this RowInfo is a part of.
	BatchIds []uint64
}

func (RowInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.RowInfo"`
}) {
}

func (x RowInfo) VDLIsZero() bool {
	if x.Op != nil && !x.Op.VDLIsZero() {
		return false
	}
	if len(x.BatchIds) != 0 {
		return false
	}
	return true
}

func (x RowInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_22); err != nil {
		return err
	}
	if x.Op != nil && !x.Op.VDLIsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Op.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.BatchIds) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_3(enc, x.BatchIds); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_3(enc vdl.Encoder, x []uint64) error {
	if err := enc.StartValue(__VDLType_list_23); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueUint(vdl.Uint64Type, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *RowInfo) VDLRead(dec vdl.Decoder) error {
	*x = RowInfo{
		Op: OperationRead{},
	}
	if err := dec.StartValue(__VDLType_struct_22); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_22 {
			index = __VDLType_struct_22.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := VDLReadOperation(dec, &x.Op); err != nil {
				return err
			}
		case 1:
			if err := __VDLReadAnon_list_3(dec, &x.BatchIds); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_3(dec vdl.Decoder, x *[]uint64) error {
	if err := dec.StartValue(__VDLType_list_23); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]uint64, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, elem, err := dec.NextEntryValueUint(64); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			*x = append(*x, elem)
		}
	}
}

type (
	// ConflictData represents any single field of the ConflictData union type.
	//
	// ConflictData represents a unit of conflict data sent over the stream. It
	// can either contain information about a Batch or about an operation done
	// on a row.
	ConflictData interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the ConflictData union type.
		__VDLReflect(__ConflictDataReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// ConflictDataBatch represents field Batch of the ConflictData union type.
	ConflictDataBatch struct{ Value BatchInfo }
	// ConflictDataRow represents field Row of the ConflictData union type.
	ConflictDataRow struct{ Value RowInfo }
	// __ConflictDataReflect describes the ConflictData union type.
	__ConflictDataReflect struct {
		Name  string `vdl:"v.io/v23/services/syncbase.ConflictData"`
		Type  ConflictData
		Union struct {
			Batch ConflictDataBatch
			Row   ConflictDataRow
		}
	}
)

func (x ConflictDataBatch) Index() int                         { return 0 }
func (x ConflictDataBatch) Interface() interface{}             { return x.Value }
func (x ConflictDataBatch) Name() string                       { return "Batch" }
func (x ConflictDataBatch) __VDLReflect(__ConflictDataReflect) {}

func (x ConflictDataRow) Index() int                         { return 1 }
func (x ConflictDataRow) Interface() interface{}             { return x.Value }
func (x ConflictDataRow) Name() string                       { return "Row" }
func (x ConflictDataRow) __VDLReflect(__ConflictDataReflect) {}

func (x ConflictDataBatch) VDLIsZero() bool {
	return x.Value == BatchInfo{}
}

func (x ConflictDataRow) VDLIsZero() bool {
	return false
}

func (x ConflictDataBatch) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_24); err != nil {
		return err
	}
	if err := enc.NextField(0); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x ConflictDataRow) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_24); err != nil {
		return err
	}
	if err := enc.NextField(1); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadConflictData(dec vdl.Decoder, x *ConflictData) error {
	if err := dec.StartValue(__VDLType_union_24); err != nil {
		return err
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_24 {
		name := decType.Field(index).Name
		index = __VDLType_union_24.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field ConflictDataBatch
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case 1:
		var field ConflictDataRow
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, x, dec.Type())
	}
	return dec.FinishValue()
}

// ConflictInfo contains information to fully specify a conflict
// for a key, providing the (local, remote, ancestor) tuple.
// A key under conflict can be a part of a batch in local, remote or both
// updates. Since the batches can have more than one key, all ConflictInfos
// for the keys within the batches are grouped together into a single conflict
// batch and sent as a stream with the Continued field representing conflict
// batch boundaries.
type ConflictInfo struct {
	// Data is a unit chunk of ConflictInfo which can be sent over the conflict
	// stream.
	Data ConflictData
	// Continued represents whether the batch of ConflictInfos has ended.
	Continued bool
}

func (ConflictInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.ConflictInfo"`
}) {
}

func (x ConflictInfo) VDLIsZero() bool {
	if x.Data != nil && !x.Data.VDLIsZero() {
		return false
	}
	if x.Continued {
		return false
	}
	return true
}

func (x ConflictInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_25); err != nil {
		return err
	}
	if x.Data != nil && !x.Data.VDLIsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Data.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Continued {
		if err := enc.NextFieldValueBool(1, vdl.BoolType, x.Continued); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ConflictInfo) VDLRead(dec vdl.Decoder) error {
	*x = ConflictInfo{
		Data: ConflictDataBatch{},
	}
	if err := dec.StartValue(__VDLType_struct_25); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_25 {
			index = __VDLType_struct_25.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := VDLReadConflictData(dec, &x.Data); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Continued = value
			}
		}
	}
}

// ValueSelection represents the value that was selected as the final resolution
// for a conflict.
type ValueSelection int

const (
	ValueSelectionLocal ValueSelection = iota
	ValueSelectionRemote
	ValueSelectionOther
)

// ValueSelectionAll holds all labels for ValueSelection.
var ValueSelectionAll = [...]ValueSelection{ValueSelectionLocal, ValueSelectionRemote, ValueSelectionOther}

// ValueSelectionFromString creates a ValueSelection from a string label.
func ValueSelectionFromString(label string) (x ValueSelection, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *ValueSelection) Set(label string) error {
	switch label {
	case "Local", "local":
		*x = ValueSelectionLocal
		return nil
	case "Remote", "remote":
		*x = ValueSelectionRemote
		return nil
	case "Other", "other":
		*x = ValueSelectionOther
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in syncbase.ValueSelection", label)
}

// String returns the string label of x.
func (x ValueSelection) String() string {
	switch x {
	case ValueSelectionLocal:
		return "Local"
	case ValueSelectionRemote:
		return "Remote"
	case ValueSelectionOther:
		return "Other"
	}
	return ""
}

func (ValueSelection) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.ValueSelection"`
	Enum struct{ Local, Remote, Other string }
}) {
}

func (x ValueSelection) VDLIsZero() bool {
	return x == ValueSelectionLocal
}

func (x ValueSelection) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_enum_26, x.String()); err != nil {
		return err
	}
	return nil
}

func (x *ValueSelection) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

// ResolutionInfo contains the application’s reply to a conflict for a key,
// providing the resolution value. The resolution may be over a group of keys
// in which case the application must send a stream of ResolutionInfos with
// the Continued field for the last ResolutionInfo representing the end of the
// batch with a value false. ResolutionInfos sent as part of a batch will be
// committed as a batch. If the commit fails, the Conflict will be re-sent.
type ResolutionInfo struct {
	// Key is the key under conflict.
	Key string
	// Selection represents the value that was selected as resolution.
	Selection ValueSelection
	// Result is the resolved value for the key. This field should be used only
	// if value of Selection field is 'Other'. If the result of a resolution is
	// delete for this key then add Value with nil Bytes.
	Result *Value
	// Continued represents whether the batch of ResolutionInfos has ended.
	Continued bool
}

func (ResolutionInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.ResolutionInfo"`
}) {
}

func (x ResolutionInfo) VDLIsZero() bool {
	return x == ResolutionInfo{}
}

func (x ResolutionInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_27); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Key); err != nil {
			return err
		}
	}
	if x.Selection != ValueSelectionLocal {
		if err := enc.NextFieldValueString(1, __VDLType_enum_26, x.Selection.String()); err != nil {
			return err
		}
	}
	if x.Result != nil {
		if err := enc.NextField(2); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := x.Result.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Continued {
		if err := enc.NextFieldValueBool(3, vdl.BoolType, x.Continued); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ResolutionInfo) VDLRead(dec vdl.Decoder) error {
	*x = ResolutionInfo{}
	if err := dec.StartValue(__VDLType_struct_27); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_27 {
			index = __VDLType_struct_27.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Key = value
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.Selection.Set(value); err != nil {
					return err
				}
			}
		case 2:
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.Result = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.Result = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.Result.VDLRead(dec); err != nil {
					return err
				}
			}
		case 3:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Continued = value
			}
		}
	}
}

// CrRule provides a filter and the type of resolution to perform for a row
// under conflict that passes the filter.
type CrRule struct {
	// CollectionId is the id of the collection that this rule applies to.
	CollectionId Id
	// KeyPrefix represents the set of keys within the given collection for which
	// this policy applies. CollectionId must not be empty if this field is set.
	KeyPrefix string
	// Type includes the full package path for the value type for which this
	// policy applies.
	Type string
	// Policy for resolving conflict.
	Resolver ResolverType
}

func (CrRule) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.CrRule"`
}) {
}

func (x CrRule) VDLIsZero() bool {
	return x == CrRule{}
}

func (x CrRule) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_28); err != nil {
		return err
	}
	if x.CollectionId != (Id{}) {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.CollectionId.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.KeyPrefix != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.KeyPrefix); err != nil {
			return err
		}
	}
	if x.Type != "" {
		if err := enc.NextFieldValueString(2, vdl.StringType, x.Type); err != nil {
			return err
		}
	}
	if x.Resolver != ResolverTypeLastWins {
		if err := enc.NextFieldValueString(3, __VDLType_enum_13, x.Resolver.String()); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CrRule) VDLRead(dec vdl.Decoder) error {
	*x = CrRule{}
	if err := dec.StartValue(__VDLType_struct_28); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_28 {
			index = __VDLType_struct_28.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.CollectionId.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.KeyPrefix = value
			}
		case 2:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Type = value
			}
		case 3:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.Resolver.Set(value); err != nil {
					return err
				}
			}
		}
	}
}

// For a given row with a conflict, all rules are matched against the row.
// If no rules match the row, we default to "LastWins". If multiple
// rules match the row, ties are broken as follows:
//  1. If one match has a longer prefix than the other, take that one.
//  2. Else, if only one match specifies a type, take that one.
//  3. Else, the two matches are identical; take the last one in the Rules array.
type CrPolicy struct {
	Rules []CrRule
}

func (CrPolicy) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.CrPolicy"`
}) {
}

func (x CrPolicy) VDLIsZero() bool {
	if len(x.Rules) != 0 {
		return false
	}
	return true
}

func (x CrPolicy) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_29); err != nil {
		return err
	}
	if len(x.Rules) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_4(enc, x.Rules); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_4(enc vdl.Encoder, x []CrRule) error {
	if err := enc.StartValue(__VDLType_list_30); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CrPolicy) VDLRead(dec vdl.Decoder) error {
	*x = CrPolicy{}
	if err := dec.StartValue(__VDLType_struct_29); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_29 {
			index = __VDLType_struct_29.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := __VDLReadAnon_list_4(dec, &x.Rules); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_4(dec vdl.Decoder, x *[]CrRule) error {
	if err := dec.StartValue(__VDLType_list_30); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]CrRule, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem CrRule
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			*x = append(*x, elem)
		}
	}
}

// SchemaMetadata maintains metadata related to the schema of a given database.
// There is one SchemaMetadata per database.
type SchemaMetadata struct {
	// Non negative Schema version number. Should be increased with every schema
	// change (e.g. adding fields to structs) that cannot be handled by previous
	// versions of the app.
	// TODO(jlodhia,ivanpi): Deprecated, needs update to multiple parallel version
	// semantics.
	Version int32
	Policy  CrPolicy
}

func (SchemaMetadata) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.SchemaMetadata"`
}) {
}

func (x SchemaMetadata) VDLIsZero() bool {
	if x.Version != 0 {
		return false
	}
	if !x.Policy.VDLIsZero() {
		return false
	}
	return true
}

func (x SchemaMetadata) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_31); err != nil {
		return err
	}
	if x.Version != 0 {
		if err := enc.NextFieldValueInt(0, vdl.Int32Type, int64(x.Version)); err != nil {
			return err
		}
	}
	if !x.Policy.VDLIsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.Policy.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SchemaMetadata) VDLRead(dec vdl.Decoder) error {
	*x = SchemaMetadata{}
	if err := dec.StartValue(__VDLType_struct_31); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_31 {
			index = __VDLType_struct_31.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueInt(32); {
			case err != nil:
				return err
			default:
				x.Version = int32(value)
			}
		case 1:
			if err := x.Policy.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

// BlobRef is a reference to a blob.
type BlobRef string

func (BlobRef) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.BlobRef"`
}) {
}

func (x BlobRef) VDLIsZero() bool {
	return x == ""
}

func (x BlobRef) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_string_32, string(x)); err != nil {
		return err
	}
	return nil
}

func (x *BlobRef) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		*x = BlobRef(value)
	}
	return nil
}

// BlobFetchState represents the state transitions of a blob fetch.
type BlobFetchState int

const (
	BlobFetchStatePending BlobFetchState = iota
	BlobFetchStateLocating
	BlobFetchStateFetching
	BlobFetchStateDone
)

// BlobFetchStateAll holds all labels for BlobFetchState.
var BlobFetchStateAll = [...]BlobFetchState{BlobFetchStatePending, BlobFetchStateLocating, BlobFetchStateFetching, BlobFetchStateDone}

// BlobFetchStateFromString creates a BlobFetchState from a string label.
func BlobFetchStateFromString(label string) (x BlobFetchState, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *BlobFetchState) Set(label string) error {
	switch label {
	case "Pending", "pending":
		*x = BlobFetchStatePending
		return nil
	case "Locating", "locating":
		*x = BlobFetchStateLocating
		return nil
	case "Fetching", "fetching":
		*x = BlobFetchStateFetching
		return nil
	case "Done", "done":
		*x = BlobFetchStateDone
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in syncbase.BlobFetchState", label)
}

// String returns the string label of x.
func (x BlobFetchState) String() string {
	switch x {
	case BlobFetchStatePending:
		return "Pending"
	case BlobFetchStateLocating:
		return "Locating"
	case BlobFetchStateFetching:
		return "Fetching"
	case BlobFetchStateDone:
		return "Done"
	}
	return ""
}

func (BlobFetchState) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.BlobFetchState"`
	Enum struct{ Pending, Locating, Fetching, Done string }
}) {
}

func (x BlobFetchState) VDLIsZero() bool {
	return x == BlobFetchStatePending
}

func (x BlobFetchState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_enum_33, x.String()); err != nil {
		return err
	}
	return nil
}

func (x *BlobFetchState) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

// BlobFetchStatus describes the progress of an asynchronous blob fetch.
type BlobFetchStatus struct {
	State    BlobFetchState // State of the blob fetch request.
	Received int64          // Total number of bytes received.
	Total    int64          // Blob size.
}

func (BlobFetchStatus) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.BlobFetchStatus"`
}) {
}

func (x BlobFetchStatus) VDLIsZero() bool {
	return x == BlobFetchStatus{}
}

func (x BlobFetchStatus) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_34); err != nil {
		return err
	}
	if x.State != BlobFetchStatePending {
		if err := enc.NextFieldValueString(0, __VDLType_enum_33, x.State.String()); err != nil {
			return err
		}
	}
	if x.Received != 0 {
		if err := enc.NextFieldValueInt(1, vdl.Int64Type, x.Received); err != nil {
			return err
		}
	}
	if x.Total != 0 {
		if err := enc.NextFieldValueInt(2, vdl.Int64Type, x.Total); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BlobFetchStatus) VDLRead(dec vdl.Decoder) error {
	*x = BlobFetchStatus{}
	if err := dec.StartValue(__VDLType_struct_34); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_34 {
			index = __VDLType_struct_34.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.State.Set(value); err != nil {
					return err
				}
			}
		case 1:
			switch value, err := dec.ReadValueInt(64); {
			case err != nil:
				return err
			default:
				x.Received = value
			}
		case 2:
			switch value, err := dec.ReadValueInt(64); {
			case err != nil:
				return err
			default:
				x.Total = value
			}
		}
	}
}

// CollectionRowPattern contains SQL LIKE-style glob patterns ('%' and '_'
// wildcards, '\' as escape character) for matching rows and collections by
// name components.
// Collection blessing and name patterns are not allowed to be empty, but the
// row key pattern is (for matching only collections and no rows).
type CollectionRowPattern struct {
	CollectionBlessing string
	CollectionName     string
	RowKey             string
}

func (CollectionRowPattern) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.CollectionRowPattern"`
}) {
}

func (x CollectionRowPattern) VDLIsZero() bool {
	return x == CollectionRowPattern{}
}

func (x CollectionRowPattern) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_35); err != nil {
		return err
	}
	if x.CollectionBlessing != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.CollectionBlessing); err != nil {
			return err
		}
	}
	if x.CollectionName != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.CollectionName); err != nil {
			return err
		}
	}
	if x.RowKey != "" {
		if err := enc.NextFieldValueString(2, vdl.StringType, x.RowKey); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CollectionRowPattern) VDLRead(dec vdl.Decoder) error {
	*x = CollectionRowPattern{}
	if err := dec.StartValue(__VDLType_struct_35); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_35 {
			index = __VDLType_struct_35.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.CollectionBlessing = value
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.CollectionName = value
			}
		case 2:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.RowKey = value
			}
		}
	}
}

// StoreChange is the new value for a watched entity.
type StoreChange struct {
	// Value is the new value for the entity if the Change state equals to Exists,
	// otherwise the Value is nil. The Value type is determined by the entity
	// type:
	// - for row updates, Value is the actual row value.
	// - for collection updates, Value is a StoreChangeCollectionInfo.
	// - for the initial root entity update, Value is nil.
	Value *vom.RawBytes
	// FromSync indicates whether the change came from sync. If FromSync is
	// false, then the change originated from the local device.
	// Note: FromSync is always false for initial state Changes.
	FromSync bool
}

func (StoreChange) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.StoreChange"`
}) {
}

func (x StoreChange) VDLIsZero() bool {
	if x.Value != nil && !x.Value.VDLIsZero() {
		return false
	}
	if x.FromSync {
		return false
	}
	return true
}

func (x StoreChange) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_36); err != nil {
		return err
	}
	if x.Value != nil && !x.Value.VDLIsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Value.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.FromSync {
		if err := enc.NextFieldValueBool(1, vdl.BoolType, x.FromSync); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *StoreChange) VDLRead(dec vdl.Decoder) error {
	*x = StoreChange{
		Value: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
	}
	if err := dec.StartValue(__VDLType_struct_36); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_36 {
			index = __VDLType_struct_36.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			x.Value = new(vom.RawBytes)
			if err := x.Value.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.FromSync = value
			}
		}
	}
}

// StoreChangeCollectionInfo represents collection metadata in a StoreChange.
type StoreChangeCollectionInfo struct {
	// Allowed lists all permissions that the client has on the collection. It is
	// separate from Perms to allow clients lacking Admin permission, who are not
	// allowed to read the full Perms, to find out what permissions they have on
	// the Collection. If the client has no Read permission (Allowed does not
	// contain Read), row updates on that collection will be silently skipped.
	// TODO(ivanpi): Row updates are currently checked against the most recently
	// committed collection permissions, which may be out of sync with the last
	// seen permissions on the watch stream (that were in effect when the row was
	// written). This can result in the watch stream skipping or failing to skip
	// rows if Read access has changed. Destroying the collection may also result
	// in skipped rows since there are no permissions to check against.
	Allowed map[access.Tag]struct{}
	// Perms contains the full collection permissions only if the client has Admin
	// permissions on the collection (Allowed contains Admin). Otherwise, Perms is
	// nil.
	// TODO(ivanpi): Update when Admin tag is split into AdminRead and AdminWrite.
	Perms access.Permissions
}

func (StoreChangeCollectionInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/syncbase.StoreChangeCollectionInfo"`
}) {
}

func (x StoreChangeCollectionInfo) VDLIsZero() bool {
	if len(x.Allowed) != 0 {
		return false
	}
	if len(x.Perms) != 0 {
		return false
	}
	return true
}

func (x StoreChangeCollectionInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_37); err != nil {
		return err
	}
	if len(x.Allowed) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_set_5(enc, x.Allowed); err != nil {
			return err
		}
	}
	if len(x.Perms) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.Perms.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_set_5(enc vdl.Encoder, x map[access.Tag]struct{}) error {
	if err := enc.StartValue(__VDLType_set_38); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key := range x {
		if err := enc.NextEntryValueString(__VDLType_string_39, string(key)); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *StoreChangeCollectionInfo) VDLRead(dec vdl.Decoder) error {
	*x = StoreChangeCollectionInfo{}
	if err := dec.StartValue(__VDLType_struct_37); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_37 {
			index = __VDLType_struct_37.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := __VDLReadAnon_set_5(dec, &x.Allowed); err != nil {
				return err
			}
		case 1:
			if err := x.Perms.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_set_5(dec vdl.Decoder, x *map[access.Tag]struct{}) error {
	if err := dec.StartValue(__VDLType_set_38); err != nil {
		return err
	}
	var tmpMap map[access.Tag]struct{}
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[access.Tag]struct{}, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			if tmpMap == nil {
				tmpMap = make(map[access.Tag]struct{})
			}
			tmpMap[access.Tag(key)] = struct{}{}
		}
	}
}

//////////////////////////////////////////////////
// Const definitions

// Access tags used in Syncbase database ACLs.
var AllDatabaseTags = []access.Tag{
	"Admin",
	"Read",
	"Write",
	"Resolve",
}

// Access tags used in Syncbase collection ACLs.
var AllCollectionTags = []access.Tag{
	"Admin",
	"Read",
	"Write",
}

// Access tags used in Syncbase syncgroup ACLs.
var AllSyncgroupTags = []access.Tag{
	"Admin",
	"Read",
}

const BlobDevTypeNormal = int32(0) // Ordinary devices (example: laptop); uses 0 value because that's the default.
const BlobDevTypeServer = int32(1) // Blobs migrate toward servers, which store them.  (example: server in cloud)
const BlobDevTypeLeaf = int32(2)   // Blobs migrate from leaves, which have less storage (examples: a camera, phone)
const NullBlobRef = BlobRef("")

// DiscoveryAttrPeer is the globally unique identifier of the advertised syncbase.
const DiscoveryAttrPeer = "p"

// DiscoveryAttrSyncgroupName is the name of the advertised syncgroup.
const DiscoveryAttrSyncgroupName = "s"

// DiscoveryAttrSyncgroupBlessing is the blessing of the creator of the syncgroup.
const DiscoveryAttrSyncgroupBlessing = "sb"

// DiscoveryAttrDatabaseName is the name component of a database ID, that this syncgroup is a part of.
const DiscoveryAttrDatabaseName = "d"

// DiscoveryAttrDatabaseBlessing is the app blessing component of a database ID,
// that this syncgroup is a part of.
const DiscoveryAttrDatabaseBlessing = "db"

//////////////////////////////////////////////////
// Error definitions

var (
	ErrNotInDevMode             = verror.Register("v.io/v23/services/syncbase.NotInDevMode", verror.NoRetry, "{1:}{2:} not running with --dev=true")
	ErrInvalidName              = verror.Register("v.io/v23/services/syncbase.InvalidName", verror.NoRetry, "{1:}{2:} invalid name: '{3}'{:_}")
	ErrCorruptDatabase          = verror.Register("v.io/v23/services/syncbase.CorruptDatabase", verror.NoRetry, "{1:}{2:} database corrupt, moved to '{3}'; client must create a new database")
	ErrUnknownBatch             = verror.Register("v.io/v23/services/syncbase.UnknownBatch", verror.NoRetry, "{1:}{2:} unknown batch, perhaps the server restarted")
	ErrNotBoundToBatch          = verror.Register("v.io/v23/services/syncbase.NotBoundToBatch", verror.NoRetry, "{1:}{2:} not bound to batch")
	ErrReadOnlyBatch            = verror.Register("v.io/v23/services/syncbase.ReadOnlyBatch", verror.NoRetry, "{1:}{2:} batch is read-only")
	ErrConcurrentBatch          = verror.Register("v.io/v23/services/syncbase.ConcurrentBatch", verror.NoRetry, "{1:}{2:} concurrent batch")
	ErrBlobNotCommitted         = verror.Register("v.io/v23/services/syncbase.BlobNotCommitted", verror.NoRetry, "{1:}{2:} blob is not yet committed")
	ErrSyncgroupJoinFailed      = verror.Register("v.io/v23/services/syncbase.SyncgroupJoinFailed", verror.NoRetry, "{1:}{2:} syncgroup join failed{:_}")
	ErrBadExecStreamHeader      = verror.Register("v.io/v23/services/syncbase.BadExecStreamHeader", verror.NoRetry, "{1:}{2:} Exec stream header improperly formatted")
	ErrInvalidPermissionsChange = verror.Register("v.io/v23/services/syncbase.InvalidPermissionsChange", verror.NoRetry, "{1:}{2:} the sequence of permission changes is invalid")
	ErrUnauthorizedCreateId     = verror.Register("v.io/v23/services/syncbase.UnauthorizedCreateId", verror.NoRetry, "{1:}{2:} not authorized to create object with id blessing '{3}' (name '{4}'){:_}")
	ErrInferAppBlessingFailed   = verror.Register("v.io/v23/services/syncbase.InferAppBlessingFailed", verror.NoRetry, "{1:}{2:} failed to infer app blessing pattern for {3} '{4}'{:_}")
	ErrInferUserBlessingFailed  = verror.Register("v.io/v23/services/syncbase.InferUserBlessingFailed", verror.NoRetry, "{1:}{2:} failed to infer user blessing pattern for {3} '{4}'{:_}")
	ErrInferDefaultPermsFailed  = verror.Register("v.io/v23/services/syncbase.InferDefaultPermsFailed", verror.NoRetry, "{1:}{2:} failed to infer default perms for user for {3} '{4}'{:_}")
)

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

// NewErrInvalidName returns an error with the ErrInvalidName ID.
func NewErrInvalidName(ctx *context.T, name string) error {
	return verror.New(ErrInvalidName, ctx, name)
}

// NewErrCorruptDatabase returns an error with the ErrCorruptDatabase ID.
func NewErrCorruptDatabase(ctx *context.T, path string) error {
	return verror.New(ErrCorruptDatabase, ctx, path)
}

// NewErrUnknownBatch returns an error with the ErrUnknownBatch ID.
func NewErrUnknownBatch(ctx *context.T) error {
	return verror.New(ErrUnknownBatch, 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)
}

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

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

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

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

// NewErrUnauthorizedCreateId returns an error with the ErrUnauthorizedCreateId ID.
func NewErrUnauthorizedCreateId(ctx *context.T, blessing string, name string) error {
	return verror.New(ErrUnauthorizedCreateId, ctx, blessing, name)
}

// NewErrInferAppBlessingFailed returns an error with the ErrInferAppBlessingFailed ID.
func NewErrInferAppBlessingFailed(ctx *context.T, entity string, name string) error {
	return verror.New(ErrInferAppBlessingFailed, ctx, entity, name)
}

// NewErrInferUserBlessingFailed returns an error with the ErrInferUserBlessingFailed ID.
func NewErrInferUserBlessingFailed(ctx *context.T, entity string, name string) error {
	return verror.New(ErrInferUserBlessingFailed, ctx, entity, name)
}

// NewErrInferDefaultPermsFailed returns an error with the ErrInferDefaultPermsFailed ID.
func NewErrInferDefaultPermsFailed(ctx *context.T, entity string, id string) error {
	return verror.New(ErrInferDefaultPermsFailed, ctx, entity, id)
}

//////////////////////////////////////////////////
// Interface definitions

// ServiceClientMethods is the client interface
// containing Service methods.
//
// Service represents a Vanadium Syncbase service.
// Service.Glob operates over Database ids, requiring Read on Service, returning
// ids sorted by blessing, then by name.
type ServiceClientMethods 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
	// DevModeUpdateVClock updates various bits of Syncbase virtual clock and
	// clock daemon state based on the specified options.
	//
	// Requires: Admin on Service.
	// Also requires --dev flag to be set.
	DevModeUpdateVClock(_ *context.T, uco DevModeUpdateVClockOpts, _ ...rpc.CallOpt) error
	// DevModeGetTime returns the current time per the Syncbase clock.
	//
	// Requires: Admin on Service.
	// Also requires --dev flag to be set.
	DevModeGetTime(*context.T, ...rpc.CallOpt) (time.Time, error)
	// DevModeGetBlobShares returns the number of ownership shares held by
	// the server for the specified blob.
	//
	// Requires: Admin on Service.
	// Also requires --dev flag to be set.
	DevModeGetBlobShares(_ *context.T, br BlobRef, _ ...rpc.CallOpt) (map[string]int32, error)
}

// ServiceClientStub adds universal methods to ServiceClientMethods.
type ServiceClientStub interface {
	ServiceClientMethods
	rpc.UniversalServiceMethods
}

// ServiceClient returns a client stub for Service.
func ServiceClient(name string) ServiceClientStub {
	return implServiceClientStub{name, permissions.ObjectClient(name)}
}

type implServiceClientStub struct {
	name string

	permissions.ObjectClientStub
}

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

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

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

// ServiceServerMethods is the interface a server writer
// implements for Service.
//
// Service represents a Vanadium Syncbase service.
// Service.Glob operates over Database ids, requiring Read on Service, returning
// ids sorted by blessing, then by name.
type ServiceServerMethods 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
	// DevModeUpdateVClock updates various bits of Syncbase virtual clock and
	// clock daemon state based on the specified options.
	//
	// Requires: Admin on Service.
	// Also requires --dev flag to be set.
	DevModeUpdateVClock(_ *context.T, _ rpc.ServerCall, uco DevModeUpdateVClockOpts) error
	// DevModeGetTime returns the current time per the Syncbase clock.
	//
	// Requires: Admin on Service.
	// Also requires --dev flag to be set.
	DevModeGetTime(*context.T, rpc.ServerCall) (time.Time, error)
	// DevModeGetBlobShares returns the number of ownership shares held by
	// the server for the specified blob.
	//
	// Requires: Admin on Service.
	// Also requires --dev flag to be set.
	DevModeGetBlobShares(_ *context.T, _ rpc.ServerCall, br BlobRef) (map[string]int32, error)
}

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

// ServiceServerStub adds universal methods to ServiceServerStubMethods.
type ServiceServerStub interface {
	ServiceServerStubMethods
	// Describe the Service interfaces.
	Describe__() []rpc.InterfaceDesc
}

// ServiceServer returns a server stub for Service.
// It converts an implementation of ServiceServerMethods into
// an object that may be used by rpc.Server.
func ServiceServer(impl ServiceServerMethods) ServiceServerStub {
	stub := implServiceServerStub{
		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 implServiceServerStub struct {
	impl ServiceServerMethods
	permissions.ObjectServerStub
	gs *rpc.GlobState
}

func (s implServiceServerStub) DevModeUpdateVClock(ctx *context.T, call rpc.ServerCall, i0 DevModeUpdateVClockOpts) error {
	return s.impl.DevModeUpdateVClock(ctx, call, i0)
}

func (s implServiceServerStub) DevModeGetTime(ctx *context.T, call rpc.ServerCall) (time.Time, error) {
	return s.impl.DevModeGetTime(ctx, call)
}

func (s implServiceServerStub) DevModeGetBlobShares(ctx *context.T, call rpc.ServerCall, i0 BlobRef) (map[string]int32, error) {
	return s.impl.DevModeGetBlobShares(ctx, call, i0)
}

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

func (s implServiceServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ServiceDesc, permissions.ObjectDesc}
}

// ServiceDesc describes the Service interface.
var ServiceDesc rpc.InterfaceDesc = descService

// descService hides the desc to keep godoc clean.
var descService = rpc.InterfaceDesc{
	Name:    "Service",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Service represents a Vanadium Syncbase service.\n// Service.Glob operates over Database ids, requiring Read on Service, returning\n// ids sorted by blessing, then by name.",
	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: "DevModeUpdateVClock",
			Doc:  "// DevModeUpdateVClock updates various bits of Syncbase virtual clock and\n// clock daemon state based on the specified options.\n//\n// Requires: Admin on Service.\n// Also requires --dev flag to be set.",
			InArgs: []rpc.ArgDesc{
				{"uco", ``}, // DevModeUpdateVClockOpts
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "DevModeGetTime",
			Doc:  "// DevModeGetTime returns the current time per the Syncbase clock.\n//\n// Requires: Admin on Service.\n// Also requires --dev flag to be set.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // time.Time
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "DevModeGetBlobShares",
			Doc:  "// DevModeGetBlobShares returns the number of ownership shares held by\n// the server for the specified blob.\n//\n// Requires: Admin on Service.\n// Also requires --dev flag to be set.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // map[string]int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
	},
}

// DatabaseWatcherClientMethods is the client interface
// containing DatabaseWatcher methods.
//
// DatabaseWatcher allows a client to watch for updates to the database. For
// each watch request, the client will receive a reliable stream of watch events
// without re-ordering. Only rows and collections matching at least one of the
// patterns are returned. Rows in collections with no Read access are also
// filtered out.
//
// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
// argument that points to a particular place in the database event log. If an
// empty ResumeMarker is provided, the WatchStream will begin with a Change
// batch containing the initial state, always starting with an empty update for
// the root entity. Otherwise, the WatchStream will contain only changes since
// the provided ResumeMarker.
// See watch.GlobWatcher for a detailed explanation of the behavior.
//
// 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
// with the Vanadium name of the watched entity relative to the database:
// - "<encCxId>/<rowKey>" for row updates
// - "<encCxId>" for collection updates
// - "" for the initial root entity update
// The Value field is a StoreChange.
// If the client has no access to a row specified in a change, that change is
// excluded from the result stream. Collection updates are always sent and can
// be used to determine that access to a collection is denied, potentially
// skipping rows.
//
// Note: A single Watch Change batch may contain changes from more than one
// batch as originally committed on a remote Syncbase or obtained from conflict
// resolution. However, changes from a single original batch will always appear
// in the same Change batch.
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.
	//
	// Requires: at least one tag on Database.
	GetResumeMarker(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (watch.ResumeMarker, error)
	// WatchPatterns returns a stream of changes that match any of the specified
	// patterns. At least one pattern must be specified.
	//
	// Requires: Read on Database.
	WatchPatterns(_ *context.T, resumeMarker watch.ResumeMarker, patterns []CollectionRowPattern, _ ...rpc.CallOpt) (DatabaseWatcherWatchPatternsClientCall, 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, i0 BatchHandle, opts ...rpc.CallOpt) (o0 watch.ResumeMarker, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetResumeMarker", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implDatabaseWatcherClientStub) WatchPatterns(ctx *context.T, i0 watch.ResumeMarker, i1 []CollectionRowPattern, opts ...rpc.CallOpt) (ocall DatabaseWatcherWatchPatternsClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "WatchPatterns", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implDatabaseWatcherWatchPatternsClientCall{ClientCall: call}
	return
}

// DatabaseWatcherWatchPatternsClientStream is the client stream for DatabaseWatcher.WatchPatterns.
type DatabaseWatcherWatchPatternsClientStream interface {
	// RecvStream returns the receiver side of the DatabaseWatcher.WatchPatterns 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() watch.Change
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// DatabaseWatcherWatchPatternsClientCall represents the call returned from DatabaseWatcher.WatchPatterns.
type DatabaseWatcherWatchPatternsClientCall interface {
	DatabaseWatcherWatchPatternsClientStream
	// 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 implDatabaseWatcherWatchPatternsClientCall struct {
	rpc.ClientCall
	valRecv watch.Change
	errRecv error
}

func (c *implDatabaseWatcherWatchPatternsClientCall) RecvStream() interface {
	Advance() bool
	Value() watch.Change
	Err() error
} {
	return implDatabaseWatcherWatchPatternsClientCallRecv{c}
}

type implDatabaseWatcherWatchPatternsClientCallRecv struct {
	c *implDatabaseWatcherWatchPatternsClientCall
}

func (c implDatabaseWatcherWatchPatternsClientCallRecv) Advance() bool {
	c.c.valRecv = watch.Change{}
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implDatabaseWatcherWatchPatternsClientCallRecv) Value() watch.Change {
	return c.c.valRecv
}
func (c implDatabaseWatcherWatchPatternsClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implDatabaseWatcherWatchPatternsClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// DatabaseWatcherServerMethods is the interface a server writer
// implements for DatabaseWatcher.
//
// DatabaseWatcher allows a client to watch for updates to the database. For
// each watch request, the client will receive a reliable stream of watch events
// without re-ordering. Only rows and collections matching at least one of the
// patterns are returned. Rows in collections with no Read access are also
// filtered out.
//
// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
// argument that points to a particular place in the database event log. If an
// empty ResumeMarker is provided, the WatchStream will begin with a Change
// batch containing the initial state, always starting with an empty update for
// the root entity. Otherwise, the WatchStream will contain only changes since
// the provided ResumeMarker.
// See watch.GlobWatcher for a detailed explanation of the behavior.
//
// 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
// with the Vanadium name of the watched entity relative to the database:
// - "<encCxId>/<rowKey>" for row updates
// - "<encCxId>" for collection updates
// - "" for the initial root entity update
// The Value field is a StoreChange.
// If the client has no access to a row specified in a change, that change is
// excluded from the result stream. Collection updates are always sent and can
// be used to determine that access to a collection is denied, potentially
// skipping rows.
//
// Note: A single Watch Change batch may contain changes from more than one
// batch as originally committed on a remote Syncbase or obtained from conflict
// resolution. However, changes from a single original batch will always appear
// in the same Change batch.
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.
	//
	// Requires: at least one tag on Database.
	GetResumeMarker(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (watch.ResumeMarker, error)
	// WatchPatterns returns a stream of changes that match any of the specified
	// patterns. At least one pattern must be specified.
	//
	// Requires: Read on Database.
	WatchPatterns(_ *context.T, _ DatabaseWatcherWatchPatternsServerCall, resumeMarker watch.ResumeMarker, patterns []CollectionRowPattern) 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.
	//
	// Requires: at least one tag on Database.
	GetResumeMarker(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (watch.ResumeMarker, error)
	// WatchPatterns returns a stream of changes that match any of the specified
	// patterns. At least one pattern must be specified.
	//
	// Requires: Read on Database.
	WatchPatterns(_ *context.T, _ *DatabaseWatcherWatchPatternsServerCallStub, resumeMarker watch.ResumeMarker, patterns []CollectionRowPattern) 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, i0 BatchHandle) (watch.ResumeMarker, error) {
	return s.impl.GetResumeMarker(ctx, call, i0)
}

func (s implDatabaseWatcherServerStub) WatchPatterns(ctx *context.T, call *DatabaseWatcherWatchPatternsServerCallStub, i0 watch.ResumeMarker, i1 []CollectionRowPattern) error {
	return s.impl.WatchPatterns(ctx, call, i0, i1)
}

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/v23/services/syncbase",
	Doc:     "// DatabaseWatcher allows a client to watch for updates to the database. For\n// each watch request, the client will receive a reliable stream of watch events\n// without re-ordering. Only rows and collections matching at least one of the\n// patterns are returned. Rows in collections with no Read access are also\n// filtered out.\n//\n// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker\n// argument that points to a particular place in the database event log. If an\n// empty ResumeMarker is provided, the WatchStream will begin with a Change\n// batch containing the initial state, always starting with an empty update for\n// the root entity. Otherwise, the WatchStream will contain only changes since\n// the provided ResumeMarker.\n// See watch.GlobWatcher for a detailed explanation of the behavior.\n//\n// The result stream consists of a never-ending sequence of Change messages\n// (until the call fails or is canceled). Each Change contains the Name field\n// with the Vanadium name of the watched entity relative to the database:\n// - \"<encCxId>/<rowKey>\" for row updates\n// - \"<encCxId>\" for collection updates\n// - \"\" for the initial root entity update\n// The Value field is a StoreChange.\n// If the client has no access to a row specified in a change, that change is\n// excluded from the result stream. Collection updates are always sent and can\n// be used to determine that access to a collection is denied, potentially\n// skipping rows.\n//\n// Note: A single Watch Change batch may contain changes from more than one\n// batch as originally committed on a remote Syncbase or obtained from conflict\n// resolution. However, changes from a single original batch will always appear\n// in the same Change batch.",
	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.\n//\n// Requires: at least one tag on Database.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // watch.ResumeMarker
			},
		},
		{
			Name: "WatchPatterns",
			Doc:  "// WatchPatterns returns a stream of changes that match any of the specified\n// patterns. At least one pattern must be specified.\n//\n// Requires: Read on Database.",
			InArgs: []rpc.ArgDesc{
				{"resumeMarker", ``}, // watch.ResumeMarker
				{"patterns", ``},     // []CollectionRowPattern
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// DatabaseWatcherWatchPatternsServerStream is the server stream for DatabaseWatcher.WatchPatterns.
type DatabaseWatcherWatchPatternsServerStream interface {
	// SendStream returns the send side of the DatabaseWatcher.WatchPatterns 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 watch.Change) error
	}
}

// DatabaseWatcherWatchPatternsServerCall represents the context passed to DatabaseWatcher.WatchPatterns.
type DatabaseWatcherWatchPatternsServerCall interface {
	rpc.ServerCall
	DatabaseWatcherWatchPatternsServerStream
}

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

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

// SendStream returns the send side of the DatabaseWatcher.WatchPatterns server stream.
func (s *DatabaseWatcherWatchPatternsServerCallStub) SendStream() interface {
	Send(item watch.Change) error
} {
	return implDatabaseWatcherWatchPatternsServerCallSend{s}
}

type implDatabaseWatcherWatchPatternsServerCallSend struct {
	s *DatabaseWatcherWatchPatternsServerCallStub
}

func (s implDatabaseWatcherWatchPatternsServerCallSend) Send(item watch.Change) error {
	return s.s.Send(item)
}

// SyncgroupManagerClientMethods is the client interface
// containing SyncgroupManager methods.
//
// SyncgroupManager is the interface for syncgroup operations. The Database is
// the parent of its syncgroups for permissions checking purposes.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncgroupManagerClientMethods interface {
	// ListSyncgroups returns a list of ids of all syncgroups attached to this
	// Database. The list is sorted by blessing, then by name.
	//
	// Requires: Read on Database.
	ListSyncgroups(*context.T, ...rpc.CallOpt) ([]Id, error)
	// CreateSyncgroup creates a new syncgroup with the given spec.
	//
	// Requires: Write on Database.
	// Also requires the creator's blessing to match the pattern in the newly
	// created syncgroup's id.
	// Permissions in spec must allow the creator at least Read access.
	// All Collections in spec must exist and the creator must have Read access
	// on them.
	// For each Collection in spec that isn't already part of another syncgroup,
	// its permissions must be signed by a blessing matching the pattern in the
	// Collection id, and all data must be signed by a blessing currently allowed
	// to Write.
	// TODO(ivanpi): Since signatures are currently not enforced, we only check
	// that the Write permissions are not empty.
	CreateSyncgroup(_ *context.T, sgId Id, spec SyncgroupSpec, myInfo SyncgroupMemberInfo, _ ...rpc.CallOpt) error
	// JoinSyncgroup joins the syncgroup.
	//
	// Requires: Write on Database and Read (no Resolve required) on syncgroup.
	// For each locally existing Collection in spec, as well as each Collection
	// in spec on the remote (joinee) Syncbase, the joiner must have Read access
	// on it.
	// For each locally existing Collection in spec that isn't already part of
	// another syncgroup, its permissions must be signed by a blessing matching
	// the pattern in the Collection id, and all data must be signed by a blessing
	// currently allowed to Write.
	// TODO(ivanpi): Since signatures are currently not enforced, we only check
	// that the Write permissions are not empty.
	JoinSyncgroup(_ *context.T, remoteSyncbaseName string, expectedSyncbaseBlessings []string, sgId Id, myInfo SyncgroupMemberInfo, _ ...rpc.CallOpt) (spec SyncgroupSpec, _ error)
	// LeaveSyncgroup leaves the syncgroup. Previously synced data will continue
	// to be available. If the last syncgroup on a Collection is left, the data
	// will become read-only and the Collection must be destroyed before joining
	// a syncgroup that includes it.
	//
	// Requires: Write on Database.
	LeaveSyncgroup(_ *context.T, sgId Id, _ ...rpc.CallOpt) error
	// DestroySyncgroup destroys the syncgroup. Previously synced data will
	// continue to be available to all members, equivalent to all members
	// leaving the syncgroup.
	//
	// Requires: Write on Database and Admin (no Resolve required) on syncgroup.
	DestroySyncgroup(_ *context.T, sgId Id, _ ...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, equivalent to having left the syncgroup.
	//
	// Requires: Admin on syncgroup.
	// The caller cannot eject themselves.
	EjectFromSyncgroup(_ *context.T, sgId Id, member string, _ ...rpc.CallOpt) error
	// GetSyncgroupSpec gets the syncgroup spec. version allows for atomic
	// read-modify-write of the spec - see comment for SetSyncgroupSpec.
	//
	// Requires: Read on syncgroup.
	GetSyncgroupSpec(_ *context.T, sgId Id, _ ...rpc.CallOpt) (spec SyncgroupSpec, version string, _ 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: Admin on syncgroup.
	// The caller must continue to have Read access.
	SetSyncgroupSpec(_ *context.T, sgId Id, spec SyncgroupSpec, version string, _ ...rpc.CallOpt) error
	// GetSyncgroupMembers gets the info objects for members of the syncgroup.
	//
	// Requires: Read on syncgroup.
	GetSyncgroupMembers(_ *context.T, sgId Id, _ ...rpc.CallOpt) (members map[string]SyncgroupMemberInfo, _ 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) ListSyncgroups(ctx *context.T, opts ...rpc.CallOpt) (o0 []Id, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ListSyncgroups", nil, []interface{}{&o0}, opts...)
	return
}

func (c implSyncgroupManagerClientStub) CreateSyncgroup(ctx *context.T, i0 Id, 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 []string, i2 Id, i3 SyncgroupMemberInfo, opts ...rpc.CallOpt) (o0 SyncgroupSpec, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "JoinSyncgroup", []interface{}{i0, i1, i2, i3}, []interface{}{&o0}, opts...)
	return
}

func (c implSyncgroupManagerClientStub) LeaveSyncgroup(ctx *context.T, i0 Id, 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 Id, 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 Id, 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 Id, 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 Id, 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 Id, 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. The Database is
// the parent of its syncgroups for permissions checking purposes.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncgroupManagerServerMethods interface {
	// ListSyncgroups returns a list of ids of all syncgroups attached to this
	// Database. The list is sorted by blessing, then by name.
	//
	// Requires: Read on Database.
	ListSyncgroups(*context.T, rpc.ServerCall) ([]Id, error)
	// CreateSyncgroup creates a new syncgroup with the given spec.
	//
	// Requires: Write on Database.
	// Also requires the creator's blessing to match the pattern in the newly
	// created syncgroup's id.
	// Permissions in spec must allow the creator at least Read access.
	// All Collections in spec must exist and the creator must have Read access
	// on them.
	// For each Collection in spec that isn't already part of another syncgroup,
	// its permissions must be signed by a blessing matching the pattern in the
	// Collection id, and all data must be signed by a blessing currently allowed
	// to Write.
	// TODO(ivanpi): Since signatures are currently not enforced, we only check
	// that the Write permissions are not empty.
	CreateSyncgroup(_ *context.T, _ rpc.ServerCall, sgId Id, spec SyncgroupSpec, myInfo SyncgroupMemberInfo) error
	// JoinSyncgroup joins the syncgroup.
	//
	// Requires: Write on Database and Read (no Resolve required) on syncgroup.
	// For each locally existing Collection in spec, as well as each Collection
	// in spec on the remote (joinee) Syncbase, the joiner must have Read access
	// on it.
	// For each locally existing Collection in spec that isn't already part of
	// another syncgroup, its permissions must be signed by a blessing matching
	// the pattern in the Collection id, and all data must be signed by a blessing
	// currently allowed to Write.
	// TODO(ivanpi): Since signatures are currently not enforced, we only check
	// that the Write permissions are not empty.
	JoinSyncgroup(_ *context.T, _ rpc.ServerCall, remoteSyncbaseName string, expectedSyncbaseBlessings []string, sgId Id, myInfo SyncgroupMemberInfo) (spec SyncgroupSpec, _ error)
	// LeaveSyncgroup leaves the syncgroup. Previously synced data will continue
	// to be available. If the last syncgroup on a Collection is left, the data
	// will become read-only and the Collection must be destroyed before joining
	// a syncgroup that includes it.
	//
	// Requires: Write on Database.
	LeaveSyncgroup(_ *context.T, _ rpc.ServerCall, sgId Id) error
	// DestroySyncgroup destroys the syncgroup. Previously synced data will
	// continue to be available to all members, equivalent to all members
	// leaving the syncgroup.
	//
	// Requires: Write on Database and Admin (no Resolve required) on syncgroup.
	DestroySyncgroup(_ *context.T, _ rpc.ServerCall, sgId Id) 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, equivalent to having left the syncgroup.
	//
	// Requires: Admin on syncgroup.
	// The caller cannot eject themselves.
	EjectFromSyncgroup(_ *context.T, _ rpc.ServerCall, sgId Id, member string) error
	// GetSyncgroupSpec gets the syncgroup spec. version allows for atomic
	// read-modify-write of the spec - see comment for SetSyncgroupSpec.
	//
	// Requires: Read on syncgroup.
	GetSyncgroupSpec(_ *context.T, _ rpc.ServerCall, sgId Id) (spec SyncgroupSpec, version string, _ 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: Admin on syncgroup.
	// The caller must continue to have Read access.
	SetSyncgroupSpec(_ *context.T, _ rpc.ServerCall, sgId Id, spec SyncgroupSpec, version string) error
	// GetSyncgroupMembers gets the info objects for members of the syncgroup.
	//
	// Requires: Read on syncgroup.
	GetSyncgroupMembers(_ *context.T, _ rpc.ServerCall, sgId Id) (members map[string]SyncgroupMemberInfo, _ 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) ListSyncgroups(ctx *context.T, call rpc.ServerCall) ([]Id, error) {
	return s.impl.ListSyncgroups(ctx, call)
}

func (s implSyncgroupManagerServerStub) CreateSyncgroup(ctx *context.T, call rpc.ServerCall, i0 Id, 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 []string, i2 Id, i3 SyncgroupMemberInfo) (SyncgroupSpec, error) {
	return s.impl.JoinSyncgroup(ctx, call, i0, i1, i2, i3)
}

func (s implSyncgroupManagerServerStub) LeaveSyncgroup(ctx *context.T, call rpc.ServerCall, i0 Id) error {
	return s.impl.LeaveSyncgroup(ctx, call, i0)
}

func (s implSyncgroupManagerServerStub) DestroySyncgroup(ctx *context.T, call rpc.ServerCall, i0 Id) error {
	return s.impl.DestroySyncgroup(ctx, call, i0)
}

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

func (s implSyncgroupManagerServerStub) GetSyncgroupSpec(ctx *context.T, call rpc.ServerCall, i0 Id) (SyncgroupSpec, string, error) {
	return s.impl.GetSyncgroupSpec(ctx, call, i0)
}

func (s implSyncgroupManagerServerStub) SetSyncgroupSpec(ctx *context.T, call rpc.ServerCall, i0 Id, 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 Id) (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/v23/services/syncbase",
	Doc:     "// SyncgroupManager is the interface for syncgroup operations. The Database is\n// the parent of its syncgroups for permissions checking purposes.\n// TODO(hpucha): Add blessings to create/join and add a refresh method.",
	Methods: []rpc.MethodDesc{
		{
			Name: "ListSyncgroups",
			Doc:  "// ListSyncgroups returns a list of ids of all syncgroups attached to this\n// Database. The list is sorted by blessing, then by name.\n//\n// Requires: Read on Database.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []Id
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "CreateSyncgroup",
			Doc:  "// CreateSyncgroup creates a new syncgroup with the given spec.\n//\n// Requires: Write on Database.\n// Also requires the creator's blessing to match the pattern in the newly\n// created syncgroup's id.\n// Permissions in spec must allow the creator at least Read access.\n// All Collections in spec must exist and the creator must have Read access\n// on them.\n// For each Collection in spec that isn't already part of another syncgroup,\n// its permissions must be signed by a blessing matching the pattern in the\n// Collection id, and all data must be signed by a blessing currently allowed\n// to Write.\n// TODO(ivanpi): Since signatures are currently not enforced, we only check\n// that the Write permissions are not empty.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``},   // Id
				{"spec", ``},   // SyncgroupSpec
				{"myInfo", ``}, // SyncgroupMemberInfo
			},
		},
		{
			Name: "JoinSyncgroup",
			Doc:  "// JoinSyncgroup joins the syncgroup.\n//\n// Requires: Write on Database and Read (no Resolve required) on syncgroup.\n// For each locally existing Collection in spec, as well as each Collection\n// in spec on the remote (joinee) Syncbase, the joiner must have Read access\n// on it.\n// For each locally existing Collection in spec that isn't already part of\n// another syncgroup, its permissions must be signed by a blessing matching\n// the pattern in the Collection id, and all data must be signed by a blessing\n// currently allowed to Write.\n// TODO(ivanpi): Since signatures are currently not enforced, we only check\n// that the Write permissions are not empty.",
			InArgs: []rpc.ArgDesc{
				{"remoteSyncbaseName", ``},        // string
				{"expectedSyncbaseBlessings", ``}, // []string
				{"sgId", ``},                      // Id
				{"myInfo", ``},                    // SyncgroupMemberInfo
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``}, // SyncgroupSpec
			},
		},
		{
			Name: "LeaveSyncgroup",
			Doc:  "// LeaveSyncgroup leaves the syncgroup. Previously synced data will continue\n// to be available. If the last syncgroup on a Collection is left, the data\n// will become read-only and the Collection must be destroyed before joining\n// a syncgroup that includes it.\n//\n// Requires: Write on Database.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "DestroySyncgroup",
			Doc:  "// DestroySyncgroup destroys the syncgroup. Previously synced data will\n// continue to be available to all members, equivalent to all members\n// leaving the syncgroup.\n//\n// Requires: Write on Database and Admin (no Resolve required) on syncgroup.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
		},
		{
			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, equivalent to having left the syncgroup.\n//\n// Requires: Admin on syncgroup.\n// The caller cannot eject themselves.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``},   // Id
				{"member", ``}, // string
			},
		},
		{
			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: Read on syncgroup.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``},    // SyncgroupSpec
				{"version", ``}, // string
			},
		},
		{
			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: Admin on syncgroup.\n// The caller must continue to have Read access.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``},    // Id
				{"spec", ``},    // SyncgroupSpec
				{"version", ``}, // string
			},
		},
		{
			Name: "GetSyncgroupMembers",
			Doc:  "// GetSyncgroupMembers gets the info objects for members of the syncgroup.\n//\n// Requires: Read on syncgroup.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
			OutArgs: []rpc.ArgDesc{
				{"members", ``}, // map[string]SyncgroupMemberInfo
			},
		},
	},
}

// BlobManagerClientMethods is the client interface
// containing BlobManager methods.
//
// BlobManager is the interface for blob operations.
//
// Description of API for resumable blob creation (append-only):
// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
//   current blob size via GetBlobSize and appending to the blob via PutBlob.
// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
//   may no longer be used.
// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
//   after commit.
type BlobManagerClientMethods interface {
	// CreateBlob returns a BlobRef for a newly created blob.
	//
	// Requires: Write on Database.
	CreateBlob(*context.T, ...rpc.CallOpt) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	//
	// Requires: Write on Database and valid BlobRef.
	PutBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) (BlobManagerPutBlobClientCall, error)
	// CommitBlob marks the blob as immutable.
	//
	// Requires: Write on Database and valid BlobRef.
	CommitBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	//
	// Requires: at least one tag on Database and valid BlobRef.
	GetBlobSize(_ *context.T, br BlobRef, _ ...rpc.CallOpt) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	//
	// Requires: at least one tag on Database and valid BlobRef.
	DeleteBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	GetBlob(_ *context.T, br BlobRef, offset int64, _ ...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.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	FetchBlob(_ *context.T, br BlobRef, priority uint64, _ ...rpc.CallOpt) (BlobManagerFetchBlobClientCall, error)
	// PinBlob locally pins the blob so that it is not evicted.
	//
	// Requires: Write on Database and valid BlobRef.
	PinBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	UnpinBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	KeepBlob(_ *context.T, br BlobRef, rank uint64, _ ...rpc.CallOpt) error
}

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

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

type implBlobManagerClientStub struct {
	name string
}

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

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

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

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

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

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

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

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

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

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

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

// BlobManagerPutBlobClientCall represents the call returned from BlobManager.PutBlob.
type BlobManagerPutBlobClientCall interface {
	BlobManagerPutBlobClientStream
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() error
}

type implBlobManagerPutBlobClientCall struct {
	rpc.ClientCall
}

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

type implBlobManagerPutBlobClientCallSend struct {
	c *implBlobManagerPutBlobClientCall
}

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

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

// BlobManagerGetBlobClientCall represents the call returned from BlobManager.GetBlob.
type BlobManagerGetBlobClientCall interface {
	BlobManagerGetBlobClientStream
	// Finish blocks until the server is done, and returns the positional return
	// values for call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() error
}

type implBlobManagerGetBlobClientCall struct {
	rpc.ClientCall
	valRecv []byte
	errRecv error
}

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

type implBlobManagerGetBlobClientCallRecv struct {
	c *implBlobManagerGetBlobClientCall
}

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

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

// BlobManagerFetchBlobClientCall represents the call returned from BlobManager.FetchBlob.
type BlobManagerFetchBlobClientCall interface {
	BlobManagerFetchBlobClientStream
	// Finish blocks until the server is done, and returns the positional return
	// values for call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() error
}

type implBlobManagerFetchBlobClientCall struct {
	rpc.ClientCall
	valRecv BlobFetchStatus
	errRecv error
}

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

type implBlobManagerFetchBlobClientCallRecv struct {
	c *implBlobManagerFetchBlobClientCall
}

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

// BlobManagerServerMethods is the interface a server writer
// implements for BlobManager.
//
// BlobManager is the interface for blob operations.
//
// Description of API for resumable blob creation (append-only):
// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
//   current blob size via GetBlobSize and appending to the blob via PutBlob.
// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
//   may no longer be used.
// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
//   after commit.
type BlobManagerServerMethods interface {
	// CreateBlob returns a BlobRef for a newly created blob.
	//
	// Requires: Write on Database.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	//
	// Requires: Write on Database and valid BlobRef.
	PutBlob(_ *context.T, _ BlobManagerPutBlobServerCall, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	//
	// Requires: Write on Database and valid BlobRef.
	CommitBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	//
	// Requires: at least one tag on Database and valid BlobRef.
	GetBlobSize(_ *context.T, _ rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	//
	// Requires: at least one tag on Database and valid BlobRef.
	DeleteBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	GetBlob(_ *context.T, _ 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.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	FetchBlob(_ *context.T, _ BlobManagerFetchBlobServerCall, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	//
	// Requires: Write on Database and valid BlobRef.
	PinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	UnpinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	KeepBlob(_ *context.T, _ 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 {
	// CreateBlob returns a BlobRef for a newly created blob.
	//
	// Requires: Write on Database.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	//
	// Requires: Write on Database and valid BlobRef.
	PutBlob(_ *context.T, _ *BlobManagerPutBlobServerCallStub, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	//
	// Requires: Write on Database and valid BlobRef.
	CommitBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	//
	// Requires: at least one tag on Database and valid BlobRef.
	GetBlobSize(_ *context.T, _ rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	//
	// Requires: at least one tag on Database and valid BlobRef.
	DeleteBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	GetBlob(_ *context.T, _ *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.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	FetchBlob(_ *context.T, _ *BlobManagerFetchBlobServerCallStub, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	//
	// Requires: Write on Database and valid BlobRef.
	PinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	UnpinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	//
	// Requires: at least one tag on Database and valid BlobRef.
	KeepBlob(_ *context.T, _ 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/v23/services/syncbase",
	Doc:     "// BlobManager is the interface for blob operations.\n//\n// Description of API for resumable blob creation (append-only):\n// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,\n//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the\n//   current blob size via GetBlobSize and appending to the blob via PutBlob.\n// - After commit, a blob is immutable, at which point PutBlob and CommitBlob\n//   may no longer be used.\n// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used\n//   after commit.",
	Methods: []rpc.MethodDesc{
		{
			Name: "CreateBlob",
			Doc:  "// CreateBlob returns a BlobRef for a newly created blob.\n//\n// Requires: Write on Database.",
			OutArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "PutBlob",
			Doc:  "// PutBlob appends the byte stream to the blob.\n//\n// Requires: Write on Database and valid BlobRef.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "CommitBlob",
			Doc:  "// CommitBlob marks the blob as immutable.\n//\n// Requires: Write on Database and valid BlobRef.",
			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).\n//\n// Requires: at least one tag on Database and valid BlobRef.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int64
			},
		},
		{
			Name: "DeleteBlob",
			Doc:  "// DeleteBlob locally deletes the blob (committed or uncommitted).\n//\n// Requires: at least one tag on Database and valid BlobRef.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
		},
		{
			Name: "GetBlob",
			Doc:  "// GetBlob returns the byte stream from a committed blob starting at offset.\n//\n// Requires: at least one tag on Database and valid BlobRef.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},     // BlobRef
				{"offset", ``}, // int64
			},
		},
		{
			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.\n//\n// Requires: at least one tag on Database and valid BlobRef.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},       // BlobRef
				{"priority", ``}, // uint64
			},
		},
		{
			Name: "PinBlob",
			Doc:  "// PinBlob locally pins the blob so that it is not evicted.\n//\n// Requires: Write on Database and valid BlobRef.",
			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.\n//\n// Requires: at least one tag on Database and valid BlobRef.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
		},
		{
			Name: "KeepBlob",
			Doc:  "// KeepBlob locally caches the blob with the specified rank. Lower\n// ranked blobs are more eagerly evicted.\n//\n// Requires: at least one tag on Database and valid BlobRef.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},   // BlobRef
				{"rank", ``}, // uint64
			},
		},
	},
}

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

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

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

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

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

type implBlobManagerPutBlobServerCallRecv struct {
	s *BlobManagerPutBlobServerCallStub
}

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

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

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

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

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

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

type implBlobManagerGetBlobServerCallSend struct {
	s *BlobManagerGetBlobServerCallStub
}

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

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

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

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

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

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

type implBlobManagerFetchBlobServerCallSend struct {
	s *BlobManagerFetchBlobServerCallStub
}

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

// SchemaManagerClientMethods is the client interface
// containing SchemaManager methods.
//
// SchemaManager implements the API for managing schema metadata attached
// to a Database.
type SchemaManagerClientMethods interface {
	// GetSchemaMetadata retrieves schema metadata for this database.
	//
	// Requires: Read on Database.
	GetSchemaMetadata(*context.T, ...rpc.CallOpt) (SchemaMetadata, error)
	// SetSchemaMetadata stores schema metadata for this database.
	//
	// Requires: Admin on Database.
	SetSchemaMetadata(_ *context.T, metadata SchemaMetadata, _ ...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: Read on Database.
	GetSchemaMetadata(*context.T, rpc.ServerCall) (SchemaMetadata, error)
	// SetSchemaMetadata stores schema metadata for this database.
	//
	// Requires: Admin on Database.
	SetSchemaMetadata(_ *context.T, _ 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/v23/services/syncbase",
	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: Read on 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: Admin on Database.",
			InArgs: []rpc.ArgDesc{
				{"metadata", ``}, // SchemaMetadata
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
	},
}

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

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

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

type implConflictManagerClientStub struct {
	name string
}

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

// ConflictManagerStartConflictResolverClientStream is the client stream for ConflictManager.StartConflictResolver.
type ConflictManagerStartConflictResolverClientStream interface {
	// RecvStream returns the receiver side of the ConflictManager.StartConflictResolver client stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() ConflictInfo
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the ConflictManager.StartConflictResolver client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item ResolutionInfo) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	}
}

// ConflictManagerStartConflictResolverClientCall represents the call returned from ConflictManager.StartConflictResolver.
type ConflictManagerStartConflictResolverClientCall interface {
	ConflictManagerStartConflictResolverClientStream
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() error
}

type implConflictManagerStartConflictResolverClientCall struct {
	rpc.ClientCall
	valRecv ConflictInfo
	errRecv error
}

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

type implConflictManagerStartConflictResolverClientCallRecv struct {
	c *implConflictManagerStartConflictResolverClientCall
}

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

type implConflictManagerStartConflictResolverClientCallSend struct {
	c *implConflictManagerStartConflictResolverClientCall
}

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

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

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

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

// ConflictManagerServer returns a server stub for ConflictManager.
// It converts an implementation of ConflictManagerServerMethods into
// an object that may be used by rpc.Server.
func ConflictManagerServer(impl ConflictManagerServerMethods) ConflictManagerServerStub {
	stub := implConflictManagerServerStub{
		impl: impl,
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implConflictManagerServerStub struct {
	impl ConflictManagerServerMethods
	gs   *rpc.GlobState
}

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

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

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

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

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

// ConflictManagerStartConflictResolverServerStream is the server stream for ConflictManager.StartConflictResolver.
type ConflictManagerStartConflictResolverServerStream interface {
	// RecvStream returns the receiver side of the ConflictManager.StartConflictResolver server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() ResolutionInfo
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the ConflictManager.StartConflictResolver server stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors encountered
		// while sending.  Blocks if there is no buffer space; will unblock when
		// buffer space is available.
		Send(item ConflictInfo) error
	}
}

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

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

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

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

type implConflictManagerStartConflictResolverServerCallRecv struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

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

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

type implConflictManagerStartConflictResolverServerCallSend struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

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

// DatabaseClientMethods is the client interface
// containing Database methods.
//
// Database represents a set of Collections. Batches, queries, syncgroups, and
// watch all operate at the Database level.
// Database.Glob operates over Collection ids, requiring Read on Database,
// returning ids sorted by blessing, then by name.
type DatabaseClientMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectClientMethods
	// DatabaseWatcher allows a client to watch for updates to the database. For
	// each watch request, the client will receive a reliable stream of watch events
	// without re-ordering. Only rows and collections matching at least one of the
	// patterns are returned. Rows in collections with no Read access are also
	// filtered out.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state, always starting with an empty update for
	// the root entity. Otherwise, the WatchStream will contain only changes since
	// the provided ResumeMarker.
	// See watch.GlobWatcher for a detailed explanation of the behavior.
	//
	// 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
	// with the Vanadium name of the watched entity relative to the database:
	// - "<encCxId>/<rowKey>" for row updates
	// - "<encCxId>" for collection updates
	// - "" for the initial root entity update
	// The Value field is a StoreChange.
	// If the client has no access to a row specified in a change, that change is
	// excluded from the result stream. Collection updates are always sent and can
	// be used to determine that access to a collection is denied, potentially
	// skipping rows.
	//
	// Note: A single Watch Change batch may contain changes from more than one
	// batch as originally committed on a remote Syncbase or obtained from conflict
	// resolution. However, changes from a single original batch will always appear
	// in the same Change batch.
	DatabaseWatcherClientMethods
	// SyncgroupManager is the interface for syncgroup operations. The Database is
	// the parent of its syncgroups for permissions checking purposes.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncgroupManagerClientMethods
	// BlobManager is the interface for blob operations.
	//
	// Description of API for resumable blob creation (append-only):
	// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
	//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
	//   current blob size via GetBlobSize and appending to the blob via PutBlob.
	// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
	//   may no longer be used.
	// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
	//   after commit.
	BlobManagerClientMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerClientMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerClientMethods
	// Create creates this Database. Permissions must be non-nil and include at
	// least one admin.
	//
	// Requires: Write on Service.
	// Also requires the creator's blessing to match the pattern in the newly
	// created Database's id. This requirement is waived for Admin on Service.
	Create(_ *context.T, metadata *SchemaMetadata, perms access.Permissions, _ ...rpc.CallOpt) error
	// Destroy destroys this Database, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	//
	// Requires: Admin on Database or Service.
	Destroy(*context.T, ...rpc.CallOpt) error
	// Exists returns true only if this Database exists.
	//
	// Requires: at least one tag on Database, or Read or Write on Service.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	Exists(*context.T, ...rpc.CallOpt) (bool, error)
	// ListCollections returns a list of ids of all Collections in this Database.
	// The list is sorted by blessing, then by name.
	// This method exists on Database but not on Service because for the latter
	// we can simply use glob, while for the former glob lists only Collections
	// visible in a new snapshot of the Database, ignoring user batches.
	// (Note that the same issue is present in glob on Collection, where Scan can
	// be used instead if batch awareness is required.)
	// TODO(sadovsky): Maybe switch to streaming RPC.
	//
	// Requires: Read on Database.
	ListCollections(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) ([]Id, error)
	// Exec executes a syncQL query with positional parameters and returns all
	// results as specified by the query's select/delete statement.
	// Concurrency semantics are documented in model.go.
	//
	// Requires: Read and/or Write on Collection, depending on the query:
	// - Read for select
	// - Read and Write for delete
	// TODO(ivanpi): Write should suffice for delete without v in WHERE clause.
	Exec(_ *context.T, bh BatchHandle, query string, params []*vom.RawBytes, _ ...rpc.CallOpt) (DatabaseExecClientCall, error)
	// BeginBatch creates a new batch. It returns a batch handle to pass in when
	// calling batch-aware RPCs.
	// Concurrency semantics are documented in model.go.
	// All batch-aware RPCs can also be called outside a batch (with an empty
	// handle), with the exception of Commit and Abort which only make sense on
	// a batch. Note that glob RPCs are not batch-aware.
	// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to
	// 'opts' once v.io/i/912 is resolved for Java.
	//
	// Requires: at least one tag on Database.
	BeginBatch(_ *context.T, bo BatchOptions, _ ...rpc.CallOpt) (BatchHandle, error)
	// Commit persists the pending changes to the database.
	// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()
	// should be used instead.
	// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.
	//
	// Requires: at least one tag on Database.
	// Also verifies that any changes to data and ACLs are allowed for the caller,
	// since the batch is signed by the committer. Since only the final value for
	// each key is committed and synced, changes to data need to be allowed by
	// the ACL before or after the batch. Specifically, adding Write permission,
	// changing a value based on it, then removing Write permission within a batch
	// is not allowed because it cannot be verified by remote peers.
	Commit(_ *context.T, bh BatchHandle, _ ...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 the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.
	//
	// Requires: at least one tag on Database.
	Abort(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
	// PauseSync pauses sync for this database. Incoming sync, as well as outgoing
	// sync of subsequent writes, will be disabled until ResumeSync is called.
	// PauseSync is idempotent.
	//
	// Requires: Admin on Database.
	PauseSync(*context.T, ...rpc.CallOpt) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	//
	// Requires: Admin on Database.
	ResumeSync(*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), ConflictManagerClient(name)}
}

type implDatabaseClientStub struct {
	name string

	permissions.ObjectClientStub
	DatabaseWatcherClientStub
	SyncgroupManagerClientStub
	BlobManagerClientStub
	SchemaManagerClientStub
	ConflictManagerClientStub
}

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

func (c implDatabaseClientStub) Destroy(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Destroy", 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) ListCollections(ctx *context.T, i0 BatchHandle, opts ...rpc.CallOpt) (o0 []Id, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ListCollections", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

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

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

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

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

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

func (c implDatabaseClientStub) ResumeSync(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "ResumeSync", 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() []*vom.RawBytes
		// 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 []*vom.RawBytes
	errRecv error
}

func (c *implDatabaseExecClientCall) RecvStream() interface {
	Advance() bool
	Value() []*vom.RawBytes
	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() []*vom.RawBytes {
	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 set of Collections. Batches, queries, syncgroups, and
// watch all operate at the Database level.
// Database.Glob operates over Collection ids, requiring Read on Database,
// returning ids sorted by blessing, then by name.
type DatabaseServerMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerMethods
	// DatabaseWatcher allows a client to watch for updates to the database. For
	// each watch request, the client will receive a reliable stream of watch events
	// without re-ordering. Only rows and collections matching at least one of the
	// patterns are returned. Rows in collections with no Read access are also
	// filtered out.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state, always starting with an empty update for
	// the root entity. Otherwise, the WatchStream will contain only changes since
	// the provided ResumeMarker.
	// See watch.GlobWatcher for a detailed explanation of the behavior.
	//
	// 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
	// with the Vanadium name of the watched entity relative to the database:
	// - "<encCxId>/<rowKey>" for row updates
	// - "<encCxId>" for collection updates
	// - "" for the initial root entity update
	// The Value field is a StoreChange.
	// If the client has no access to a row specified in a change, that change is
	// excluded from the result stream. Collection updates are always sent and can
	// be used to determine that access to a collection is denied, potentially
	// skipping rows.
	//
	// Note: A single Watch Change batch may contain changes from more than one
	// batch as originally committed on a remote Syncbase or obtained from conflict
	// resolution. However, changes from a single original batch will always appear
	// in the same Change batch.
	DatabaseWatcherServerMethods
	// SyncgroupManager is the interface for syncgroup operations. The Database is
	// the parent of its syncgroups for permissions checking purposes.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncgroupManagerServerMethods
	// BlobManager is the interface for blob operations.
	//
	// Description of API for resumable blob creation (append-only):
	// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
	//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
	//   current blob size via GetBlobSize and appending to the blob via PutBlob.
	// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
	//   may no longer be used.
	// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
	//   after commit.
	BlobManagerServerMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerServerMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerServerMethods
	// Create creates this Database. Permissions must be non-nil and include at
	// least one admin.
	//
	// Requires: Write on Service.
	// Also requires the creator's blessing to match the pattern in the newly
	// created Database's id. This requirement is waived for Admin on Service.
	Create(_ *context.T, _ rpc.ServerCall, metadata *SchemaMetadata, perms access.Permissions) error
	// Destroy destroys this Database, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	//
	// Requires: Admin on Database or Service.
	Destroy(*context.T, rpc.ServerCall) error
	// Exists returns true only if this Database exists.
	//
	// Requires: at least one tag on Database, or Read or Write on Service.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	Exists(*context.T, rpc.ServerCall) (bool, error)
	// ListCollections returns a list of ids of all Collections in this Database.
	// The list is sorted by blessing, then by name.
	// This method exists on Database but not on Service because for the latter
	// we can simply use glob, while for the former glob lists only Collections
	// visible in a new snapshot of the Database, ignoring user batches.
	// (Note that the same issue is present in glob on Collection, where Scan can
	// be used instead if batch awareness is required.)
	// TODO(sadovsky): Maybe switch to streaming RPC.
	//
	// Requires: Read on Database.
	ListCollections(_ *context.T, _ rpc.ServerCall, bh BatchHandle) ([]Id, error)
	// Exec executes a syncQL query with positional parameters and returns all
	// results as specified by the query's select/delete statement.
	// Concurrency semantics are documented in model.go.
	//
	// Requires: Read and/or Write on Collection, depending on the query:
	// - Read for select
	// - Read and Write for delete
	// TODO(ivanpi): Write should suffice for delete without v in WHERE clause.
	Exec(_ *context.T, _ DatabaseExecServerCall, bh BatchHandle, query string, params []*vom.RawBytes) error
	// BeginBatch creates a new batch. It returns a batch handle to pass in when
	// calling batch-aware RPCs.
	// Concurrency semantics are documented in model.go.
	// All batch-aware RPCs can also be called outside a batch (with an empty
	// handle), with the exception of Commit and Abort which only make sense on
	// a batch. Note that glob RPCs are not batch-aware.
	// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to
	// 'opts' once v.io/i/912 is resolved for Java.
	//
	// Requires: at least one tag on Database.
	BeginBatch(_ *context.T, _ rpc.ServerCall, bo BatchOptions) (BatchHandle, error)
	// Commit persists the pending changes to the database.
	// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()
	// should be used instead.
	// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.
	//
	// Requires: at least one tag on Database.
	// Also verifies that any changes to data and ACLs are allowed for the caller,
	// since the batch is signed by the committer. Since only the final value for
	// each key is committed and synced, changes to data need to be allowed by
	// the ACL before or after the batch. Specifically, adding Write permission,
	// changing a value based on it, then removing Write permission within a batch
	// is not allowed because it cannot be verified by remote peers.
	Commit(_ *context.T, _ rpc.ServerCall, bh BatchHandle) 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 the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.
	//
	// Requires: at least one tag on Database.
	Abort(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// PauseSync pauses sync for this database. Incoming sync, as well as outgoing
	// sync of subsequent writes, will be disabled until ResumeSync is called.
	// PauseSync is idempotent.
	//
	// Requires: Admin on Database.
	PauseSync(*context.T, rpc.ServerCall) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	//
	// Requires: Admin on Database.
	ResumeSync(*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
	// DatabaseWatcher allows a client to watch for updates to the database. For
	// each watch request, the client will receive a reliable stream of watch events
	// without re-ordering. Only rows and collections matching at least one of the
	// patterns are returned. Rows in collections with no Read access are also
	// filtered out.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state, always starting with an empty update for
	// the root entity. Otherwise, the WatchStream will contain only changes since
	// the provided ResumeMarker.
	// See watch.GlobWatcher for a detailed explanation of the behavior.
	//
	// 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
	// with the Vanadium name of the watched entity relative to the database:
	// - "<encCxId>/<rowKey>" for row updates
	// - "<encCxId>" for collection updates
	// - "" for the initial root entity update
	// The Value field is a StoreChange.
	// If the client has no access to a row specified in a change, that change is
	// excluded from the result stream. Collection updates are always sent and can
	// be used to determine that access to a collection is denied, potentially
	// skipping rows.
	//
	// Note: A single Watch Change batch may contain changes from more than one
	// batch as originally committed on a remote Syncbase or obtained from conflict
	// resolution. However, changes from a single original batch will always appear
	// in the same Change batch.
	DatabaseWatcherServerStubMethods
	// SyncgroupManager is the interface for syncgroup operations. The Database is
	// the parent of its syncgroups for permissions checking purposes.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncgroupManagerServerStubMethods
	// BlobManager is the interface for blob operations.
	//
	// Description of API for resumable blob creation (append-only):
	// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
	//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
	//   current blob size via GetBlobSize and appending to the blob via PutBlob.
	// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
	//   may no longer be used.
	// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
	//   after commit.
	BlobManagerServerStubMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerServerStubMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerServerStubMethods
	// Create creates this Database. Permissions must be non-nil and include at
	// least one admin.
	//
	// Requires: Write on Service.
	// Also requires the creator's blessing to match the pattern in the newly
	// created Database's id. This requirement is waived for Admin on Service.
	Create(_ *context.T, _ rpc.ServerCall, metadata *SchemaMetadata, perms access.Permissions) error
	// Destroy destroys this Database, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	//
	// Requires: Admin on Database or Service.
	Destroy(*context.T, rpc.ServerCall) error
	// Exists returns true only if this Database exists.
	//
	// Requires: at least one tag on Database, or Read or Write on Service.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	Exists(*context.T, rpc.ServerCall) (bool, error)
	// ListCollections returns a list of ids of all Collections in this Database.
	// The list is sorted by blessing, then by name.
	// This method exists on Database but not on Service because for the latter
	// we can simply use glob, while for the former glob lists only Collections
	// visible in a new snapshot of the Database, ignoring user batches.
	// (Note that the same issue is present in glob on Collection, where Scan can
	// be used instead if batch awareness is required.)
	// TODO(sadovsky): Maybe switch to streaming RPC.
	//
	// Requires: Read on Database.
	ListCollections(_ *context.T, _ rpc.ServerCall, bh BatchHandle) ([]Id, error)
	// Exec executes a syncQL query with positional parameters and returns all
	// results as specified by the query's select/delete statement.
	// Concurrency semantics are documented in model.go.
	//
	// Requires: Read and/or Write on Collection, depending on the query:
	// - Read for select
	// - Read and Write for delete
	// TODO(ivanpi): Write should suffice for delete without v in WHERE clause.
	Exec(_ *context.T, _ *DatabaseExecServerCallStub, bh BatchHandle, query string, params []*vom.RawBytes) error
	// BeginBatch creates a new batch. It returns a batch handle to pass in when
	// calling batch-aware RPCs.
	// Concurrency semantics are documented in model.go.
	// All batch-aware RPCs can also be called outside a batch (with an empty
	// handle), with the exception of Commit and Abort which only make sense on
	// a batch. Note that glob RPCs are not batch-aware.
	// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to
	// 'opts' once v.io/i/912 is resolved for Java.
	//
	// Requires: at least one tag on Database.
	BeginBatch(_ *context.T, _ rpc.ServerCall, bo BatchOptions) (BatchHandle, error)
	// Commit persists the pending changes to the database.
	// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()
	// should be used instead.
	// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.
	//
	// Requires: at least one tag on Database.
	// Also verifies that any changes to data and ACLs are allowed for the caller,
	// since the batch is signed by the committer. Since only the final value for
	// each key is committed and synced, changes to data need to be allowed by
	// the ACL before or after the batch. Specifically, adding Write permission,
	// changing a value based on it, then removing Write permission within a batch
	// is not allowed because it cannot be verified by remote peers.
	Commit(_ *context.T, _ rpc.ServerCall, bh BatchHandle) 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 the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.
	//
	// Requires: at least one tag on Database.
	Abort(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// PauseSync pauses sync for this database. Incoming sync, as well as outgoing
	// sync of subsequent writes, will be disabled until ResumeSync is called.
	// PauseSync is idempotent.
	//
	// Requires: Admin on Database.
	PauseSync(*context.T, rpc.ServerCall) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	//
	// Requires: Admin on Database.
	ResumeSync(*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),
		ConflictManagerServerStub:  ConflictManagerServer(impl),
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implDatabaseServerStub struct {
	impl DatabaseServerMethods
	permissions.ObjectServerStub
	DatabaseWatcherServerStub
	SyncgroupManagerServerStub
	BlobManagerServerStub
	SchemaManagerServerStub
	ConflictManagerServerStub
	gs *rpc.GlobState
}

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

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

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

func (s implDatabaseServerStub) ListCollections(ctx *context.T, call rpc.ServerCall, i0 BatchHandle) ([]Id, error) {
	return s.impl.ListCollections(ctx, call, i0)
}

func (s implDatabaseServerStub) Exec(ctx *context.T, call *DatabaseExecServerCallStub, i0 BatchHandle, i1 string, i2 []*vom.RawBytes) error {
	return s.impl.Exec(ctx, call, i0, i1, i2)
}

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

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

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

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

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

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

// descDatabase hides the desc to keep godoc clean.
var descDatabase = rpc.InterfaceDesc{
	Name:    "Database",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Database represents a set of Collections. Batches, queries, syncgroups, and\n// watch all operate at the Database level.\n// Database.Glob operates over Collection ids, requiring Read on Database,\n// returning ids sorted by blessing, then by name.",
	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/v23/services/syncbase", "// DatabaseWatcher allows a client to watch for updates to the database. For\n// each watch request, the client will receive a reliable stream of watch events\n// without re-ordering. Only rows and collections matching at least one of the\n// patterns are returned. Rows in collections with no Read access are also\n// filtered out.\n//\n// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker\n// argument that points to a particular place in the database event log. If an\n// empty ResumeMarker is provided, the WatchStream will begin with a Change\n// batch containing the initial state, always starting with an empty update for\n// the root entity. Otherwise, the WatchStream will contain only changes since\n// the provided ResumeMarker.\n// See watch.GlobWatcher for a detailed explanation of the behavior.\n//\n// The result stream consists of a never-ending sequence of Change messages\n// (until the call fails or is canceled). Each Change contains the Name field\n// with the Vanadium name of the watched entity relative to the database:\n// - \"<encCxId>/<rowKey>\" for row updates\n// - \"<encCxId>\" for collection updates\n// - \"\" for the initial root entity update\n// The Value field is a StoreChange.\n// If the client has no access to a row specified in a change, that change is\n// excluded from the result stream. Collection updates are always sent and can\n// be used to determine that access to a collection is denied, potentially\n// skipping rows.\n//\n// Note: A single Watch Change batch may contain changes from more than one\n// batch as originally committed on a remote Syncbase or obtained from conflict\n// resolution. However, changes from a single original batch will always appear\n// in the same Change batch."},
		{"SyncgroupManager", "v.io/v23/services/syncbase", "// SyncgroupManager is the interface for syncgroup operations. The Database is\n// the parent of its syncgroups for permissions checking purposes.\n// TODO(hpucha): Add blessings to create/join and add a refresh method."},
		{"BlobManager", "v.io/v23/services/syncbase", "// BlobManager is the interface for blob operations.\n//\n// Description of API for resumable blob creation (append-only):\n// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,\n//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the\n//   current blob size via GetBlobSize and appending to the blob via PutBlob.\n// - After commit, a blob is immutable, at which point PutBlob and CommitBlob\n//   may no longer be used.\n// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used\n//   after commit."},
		{"SchemaManager", "v.io/v23/services/syncbase", "// SchemaManager implements the API for managing schema metadata attached\n// to a Database."},
		{"ConflictManager", "v.io/v23/services/syncbase", "// ConflictManager interface provides all the methods necessary to handle\n// conflict resolution for a given database."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Database. Permissions must be non-nil and include at\n// least one admin.\n//\n// Requires: Write on Service.\n// Also requires the creator's blessing to match the pattern in the newly\n// created Database's id. This requirement is waived for Admin on Service.",
			InArgs: []rpc.ArgDesc{
				{"metadata", ``}, // *SchemaMetadata
				{"perms", ``},    // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Destroy",
			Doc:  "// Destroy destroys this Database, permanently removing all of its data.\n// TODO(sadovsky): Specify what happens to syncgroups.\n//\n// Requires: Admin on Database or Service.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Database exists.\n//\n// Requires: at least one tag on Database, or Read or Write on Service.\n// Otherwise, ErrNoExistOrNoAccess is returned.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
		},
		{
			Name: "ListCollections",
			Doc:  "// ListCollections returns a list of ids of all Collections in this Database.\n// The list is sorted by blessing, then by name.\n// This method exists on Database but not on Service because for the latter\n// we can simply use glob, while for the former glob lists only Collections\n// visible in a new snapshot of the Database, ignoring user batches.\n// (Note that the same issue is present in glob on Collection, where Scan can\n// be used instead if batch awareness is required.)\n// TODO(sadovsky): Maybe switch to streaming RPC.\n//\n// Requires: Read on Database.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []Id
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Exec",
			Doc:  "// Exec executes a syncQL query with positional parameters and returns all\n// results as specified by the query's select/delete statement.\n// Concurrency semantics are documented in model.go.\n//\n// Requires: Read and/or Write on Collection, depending on the query:\n// - Read for select\n// - Read and Write for delete\n// TODO(ivanpi): Write should suffice for delete without v in WHERE clause.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},     // BatchHandle
				{"query", ``},  // string
				{"params", ``}, // []*vom.RawBytes
			},
		},
		{
			Name: "BeginBatch",
			Doc:  "// BeginBatch creates a new batch. It returns a batch handle to pass in when\n// calling batch-aware RPCs.\n// Concurrency semantics are documented in model.go.\n// All batch-aware RPCs can also be called outside a batch (with an empty\n// handle), with the exception of Commit and Abort which only make sense on\n// a batch. Note that glob RPCs are not batch-aware.\n// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to\n// 'opts' once v.io/i/912 is resolved for Java.\n//\n// Requires: at least one tag on Database.",
			InArgs: []rpc.ArgDesc{
				{"bo", ``}, // BatchOptions
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // BatchHandle
			},
		},
		{
			Name: "Commit",
			Doc:  "// Commit persists the pending changes to the database.\n// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()\n// should be used instead.\n// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.\n//\n// Requires: at least one tag on Database.\n// Also verifies that any changes to data and ACLs are allowed for the caller,\n// since the batch is signed by the committer. Since only the final value for\n// each key is committed and synced, changes to data need to be allowed by\n// the ACL before or after the batch. Specifically, adding Write permission,\n// changing a value based on it, then removing Write permission within a batch\n// is not allowed because it cannot be verified by remote peers.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
		},
		{
			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 the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.\n//\n// Requires: at least one tag on Database.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
		},
		{
			Name: "PauseSync",
			Doc:  "// PauseSync pauses sync for this database. Incoming sync, as well as outgoing\n// sync of subsequent writes, will be disabled until ResumeSync is called.\n// PauseSync is idempotent.\n//\n// Requires: Admin on Database.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "ResumeSync",
			Doc:  "// ResumeSync resumes sync for this database. ResumeSync is idempotent.\n//\n// Requires: Admin on Database.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
	},
}

// 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 []*vom.RawBytes) 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 []*vom.RawBytes) error
} {
	return implDatabaseExecServerCallSend{s}
}

type implDatabaseExecServerCallSend struct {
	s *DatabaseExecServerCallStub
}

func (s implDatabaseExecServerCallSend) Send(item []*vom.RawBytes) error {
	return s.s.Send(item)
}

// CollectionClientMethods is the client interface
// containing Collection methods.
//
// Collection represents a set of Rows.
// Collection.Glob operates over keys of Rows in the Collection, requiring Read
// on Collection, returning keys in a lexicographically sorted order.
type CollectionClientMethods interface {
	// Create creates this Collection. Permissions must be non-nil and include at
	// least one admin.
	//
	// Requires: Write on Database.
	// Also requires the creator's blessing to match the pattern in the newly
	// created Collection's id.
	Create(_ *context.T, bh BatchHandle, perms access.Permissions, _ ...rpc.CallOpt) error
	// Destroy destroys this Collection, permanently removing all of its data.
	//
	// Requires: Admin on Collection or on Database.
	// TODO(ivanpi): Prevent for synced Collections.
	Destroy(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
	// Exists returns true only if this Collection exists.
	//
	// Requires: at least one tag on Collection, or Read or Write on Database.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	// If Database does not exist, returned value is identical to
	// Database.Exists().
	Exists(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	//
	// Requires: Admin on Collection.
	GetPermissions(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the Collection.
	// Permissions must include at least one admin.
	//
	// Requires: Admin on Collection.
	SetPermissions(_ *context.T, bh BatchHandle, perms access.Permissions, _ ...rpc.CallOpt) error
	// DeleteRange deletes all rows in the given half-open range [start, limit).
	// If limit is "", all rows with keys >= start are included.
	//
	// Requires: Write on Collection.
	DeleteRange(_ *context.T, bh BatchHandle, start []byte, limit []byte, _ ...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.
	// Note, we use []byte rather than string for start and limit because they
	// need not be valid UTF-8; VDL expects strings to be valid UTF-8.
	//
	// Requires: Read on Collection.
	Scan(_ *context.T, bh BatchHandle, start []byte, limit []byte, _ ...rpc.CallOpt) (CollectionScanClientCall, error)
}

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

// CollectionClient returns a client stub for Collection.
func CollectionClient(name string) CollectionClientStub {
	return implCollectionClientStub{name}
}

type implCollectionClientStub struct {
	name string
}

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

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

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

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

func (c implCollectionClientStub) SetPermissions(ctx *context.T, i0 BatchHandle, 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 implCollectionClientStub) DeleteRange(ctx *context.T, i0 BatchHandle, i1 []byte, i2 []byte, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "DeleteRange", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

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

// CollectionScanClientStream is the client stream for Collection.Scan.
type CollectionScanClientStream interface {
	// RecvStream returns the receiver side of the Collection.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
	}
}

// CollectionScanClientCall represents the call returned from Collection.Scan.
type CollectionScanClientCall interface {
	CollectionScanClientStream
	// 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 implCollectionScanClientCall struct {
	rpc.ClientCall
	valRecv KeyValue
	errRecv error
}

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

type implCollectionScanClientCallRecv struct {
	c *implCollectionScanClientCall
}

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

// CollectionServerMethods is the interface a server writer
// implements for Collection.
//
// Collection represents a set of Rows.
// Collection.Glob operates over keys of Rows in the Collection, requiring Read
// on Collection, returning keys in a lexicographically sorted order.
type CollectionServerMethods interface {
	// Create creates this Collection. Permissions must be non-nil and include at
	// least one admin.
	//
	// Requires: Write on Database.
	// Also requires the creator's blessing to match the pattern in the newly
	// created Collection's id.
	Create(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// Destroy destroys this Collection, permanently removing all of its data.
	//
	// Requires: Admin on Collection or on Database.
	// TODO(ivanpi): Prevent for synced Collections.
	Destroy(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Exists returns true only if this Collection exists.
	//
	// Requires: at least one tag on Collection, or Read or Write on Database.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	// If Database does not exist, returned value is identical to
	// Database.Exists().
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	//
	// Requires: Admin on Collection.
	GetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the Collection.
	// Permissions must include at least one admin.
	//
	// Requires: Admin on Collection.
	SetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// DeleteRange deletes all rows in the given half-open range [start, limit).
	// If limit is "", all rows with keys >= start are included.
	//
	// Requires: Write on Collection.
	DeleteRange(_ *context.T, _ rpc.ServerCall, bh BatchHandle, 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.
	// Note, we use []byte rather than string for start and limit because they
	// need not be valid UTF-8; VDL expects strings to be valid UTF-8.
	//
	// Requires: Read on Collection.
	Scan(_ *context.T, _ CollectionScanServerCall, bh BatchHandle, start []byte, limit []byte) error
}

// CollectionServerStubMethods is the server interface containing
// Collection methods, as expected by rpc.Server.
// The only difference between this interface and CollectionServerMethods
// is the streaming methods.
type CollectionServerStubMethods interface {
	// Create creates this Collection. Permissions must be non-nil and include at
	// least one admin.
	//
	// Requires: Write on Database.
	// Also requires the creator's blessing to match the pattern in the newly
	// created Collection's id.
	Create(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// Destroy destroys this Collection, permanently removing all of its data.
	//
	// Requires: Admin on Collection or on Database.
	// TODO(ivanpi): Prevent for synced Collections.
	Destroy(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Exists returns true only if this Collection exists.
	//
	// Requires: at least one tag on Collection, or Read or Write on Database.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	// If Database does not exist, returned value is identical to
	// Database.Exists().
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	//
	// Requires: Admin on Collection.
	GetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the Collection.
	// Permissions must include at least one admin.
	//
	// Requires: Admin on Collection.
	SetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// DeleteRange deletes all rows in the given half-open range [start, limit).
	// If limit is "", all rows with keys >= start are included.
	//
	// Requires: Write on Collection.
	DeleteRange(_ *context.T, _ rpc.ServerCall, bh BatchHandle, 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.
	// Note, we use []byte rather than string for start and limit because they
	// need not be valid UTF-8; VDL expects strings to be valid UTF-8.
	//
	// Requires: Read on Collection.
	Scan(_ *context.T, _ *CollectionScanServerCallStub, bh BatchHandle, start []byte, limit []byte) error
}

// CollectionServerStub adds universal methods to CollectionServerStubMethods.
type CollectionServerStub interface {
	CollectionServerStubMethods
	// Describe the Collection interfaces.
	Describe__() []rpc.InterfaceDesc
}

// CollectionServer returns a server stub for Collection.
// It converts an implementation of CollectionServerMethods into
// an object that may be used by rpc.Server.
func CollectionServer(impl CollectionServerMethods) CollectionServerStub {
	stub := implCollectionServerStub{
		impl: impl,
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

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

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

func (s implCollectionServerStub) Destroy(ctx *context.T, call rpc.ServerCall, i0 BatchHandle) error {
	return s.impl.Destroy(ctx, call, i0)
}

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

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

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

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

func (s implCollectionServerStub) Scan(ctx *context.T, call *CollectionScanServerCallStub, i0 BatchHandle, i1 []byte, i2 []byte) error {
	return s.impl.Scan(ctx, call, i0, i1, i2)
}

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

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

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

// descCollection hides the desc to keep godoc clean.
var descCollection = rpc.InterfaceDesc{
	Name:    "Collection",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Collection represents a set of Rows.\n// Collection.Glob operates over keys of Rows in the Collection, requiring Read\n// on Collection, returning keys in a lexicographically sorted order.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Collection. Permissions must be non-nil and include at\n// least one admin.\n//\n// Requires: Write on Database.\n// Also requires the creator's blessing to match the pattern in the newly\n// created Collection's id.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"perms", ``}, // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Destroy",
			Doc:  "// Destroy destroys this Collection, permanently removing all of its data.\n//\n// Requires: Admin on Collection or on Database.\n// TODO(ivanpi): Prevent for synced Collections.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Collection exists.\n//\n// Requires: at least one tag on Collection, or Read or Write on Database.\n// Otherwise, ErrNoExistOrNoAccess is returned.\n// If Database does not exist, returned value is identical to\n// Database.Exists().",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
		},
		{
			Name: "GetPermissions",
			Doc:  "// GetPermissions returns the current Permissions for the Collection.\n//\n// Requires: Admin on Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "SetPermissions",
			Doc:  "// SetPermissions replaces the current Permissions for the Collection.\n// Permissions must include at least one admin.\n//\n// Requires: Admin on Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"perms", ``}, // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "DeleteRange",
			Doc:  "// DeleteRange deletes all rows in the given half-open range [start, limit).\n// If limit is \"\", all rows with keys >= start are included.\n//\n// Requires: Write on Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"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.\n// Concurrency semantics are documented in model.go.\n// Note, we use []byte rather than string for start and limit because they\n// need not be valid UTF-8; VDL expects strings to be valid UTF-8.\n//\n// Requires: Read on Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"start", ``}, // []byte
				{"limit", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// CollectionScanServerStream is the server stream for Collection.Scan.
type CollectionScanServerStream interface {
	// SendStream returns the send side of the Collection.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
	}
}

// CollectionScanServerCall represents the context passed to Collection.Scan.
type CollectionScanServerCall interface {
	rpc.ServerCall
	CollectionScanServerStream
}

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

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

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

type implCollectionScanServerCallSend struct {
	s *CollectionScanServerCallStub
}

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

// RowClientMethods is the client interface
// containing Row methods.
//
// Row represents a single row in a Collection.
// All access checks are performed against the Collection ACL.
type RowClientMethods interface {
	// Exists returns true only if this Row exists.
	//
	// Requires: Read or Write on Collection.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	// If Collection does not exist, returned value is identical to
	// Collection.Exists().
	// Note, write methods on Row do not leak information whether the Row existed
	// before, but Write is sufficient to call Exists. Therefore, Read protects
	// Row data and listing, but not Row existence.
	Exists(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (bool, error)
	// Get returns the value for this Row.
	//
	// Requires: Read on Collection.
	Get(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (*vom.RawBytes, error)
	// Put writes the given value for this Row.
	//
	// Requires: Write on Collection.
	Put(_ *context.T, bh BatchHandle, value *vom.RawBytes, _ ...rpc.CallOpt) error
	// Delete deletes this Row.
	//
	// Requires: Write on Collection.
	Delete(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
}

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

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

type implRowClientStub struct {
	name string
}

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

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

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

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

// RowServerMethods is the interface a server writer
// implements for Row.
//
// Row represents a single row in a Collection.
// All access checks are performed against the Collection ACL.
type RowServerMethods interface {
	// Exists returns true only if this Row exists.
	//
	// Requires: Read or Write on Collection.
	// Otherwise, ErrNoExistOrNoAccess is returned.
	// If Collection does not exist, returned value is identical to
	// Collection.Exists().
	// Note, write methods on Row do not leak information whether the Row existed
	// before, but Write is sufficient to call Exists. Therefore, Read protects
	// Row data and listing, but not Row existence.
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// Get returns the value for this Row.
	//
	// Requires: Read on Collection.
	Get(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (*vom.RawBytes, error)
	// Put writes the given value for this Row.
	//
	// Requires: Write on Collection.
	Put(_ *context.T, _ rpc.ServerCall, bh BatchHandle, value *vom.RawBytes) error
	// Delete deletes this Row.
	//
	// Requires: Write on Collection.
	Delete(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
}

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

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

// RowServer returns a server stub for Row.
// It converts an implementation of RowServerMethods into
// an object that may be used by rpc.Server.
func RowServer(impl RowServerMethods) RowServerStub {
	stub := implRowServerStub{
		impl: impl,
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implRowServerStub struct {
	impl RowServerMethods
	gs   *rpc.GlobState
}

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

func (s implRowServerStub) Get(ctx *context.T, call rpc.ServerCall, i0 BatchHandle) (*vom.RawBytes, error) {
	return s.impl.Get(ctx, call, i0)
}

func (s implRowServerStub) Put(ctx *context.T, call rpc.ServerCall, i0 BatchHandle, i1 *vom.RawBytes) error {
	return s.impl.Put(ctx, call, i0, i1)
}

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

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

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

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

// descRow hides the desc to keep godoc clean.
var descRow = rpc.InterfaceDesc{
	Name:    "Row",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Row represents a single row in a Collection.\n// All access checks are performed against the Collection ACL.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Row exists.\n//\n// Requires: Read or Write on Collection.\n// Otherwise, ErrNoExistOrNoAccess is returned.\n// If Collection does not exist, returned value is identical to\n// Collection.Exists().\n// Note, write methods on Row do not leak information whether the Row existed\n// before, but Write is sufficient to call Exists. Therefore, Read protects\n// Row data and listing, but not Row existence.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
		},
		{
			Name: "Get",
			Doc:  "// Get returns the value for this Row.\n//\n// Requires: Read on Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // *vom.RawBytes
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Put",
			Doc:  "// Put writes the given value for this Row.\n//\n// Requires: Write on Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"value", ``}, // *vom.RawBytes
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Row.\n//\n// Requires: Write on Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1    *vdl.Type
	__VDLType_struct_2    *vdl.Type
	__VDLType_struct_3    *vdl.Type
	__VDLType_struct_4    *vdl.Type
	__VDLType_struct_5    *vdl.Type
	__VDLType_string_6    *vdl.Type
	__VDLType_struct_7    *vdl.Type
	__VDLType_struct_8    *vdl.Type
	__VDLType_map_9       *vdl.Type
	__VDLType_list_10     *vdl.Type
	__VDLType_list_11     *vdl.Type
	__VDLType_struct_12   *vdl.Type
	__VDLType_enum_13     *vdl.Type
	__VDLType_enum_14     *vdl.Type
	__VDLType_struct_15   *vdl.Type
	__VDLType_enum_16     *vdl.Type
	__VDLType_struct_17   *vdl.Type
	__VDLType_struct_18   *vdl.Type
	__VDLType_optional_19 *vdl.Type
	__VDLType_struct_20   *vdl.Type
	__VDLType_union_21    *vdl.Type
	__VDLType_struct_22   *vdl.Type
	__VDLType_list_23     *vdl.Type
	__VDLType_union_24    *vdl.Type
	__VDLType_struct_25   *vdl.Type
	__VDLType_enum_26     *vdl.Type
	__VDLType_struct_27   *vdl.Type
	__VDLType_struct_28   *vdl.Type
	__VDLType_struct_29   *vdl.Type
	__VDLType_list_30     *vdl.Type
	__VDLType_struct_31   *vdl.Type
	__VDLType_string_32   *vdl.Type
	__VDLType_enum_33     *vdl.Type
	__VDLType_struct_34   *vdl.Type
	__VDLType_struct_35   *vdl.Type
	__VDLType_struct_36   *vdl.Type
	__VDLType_struct_37   *vdl.Type
	__VDLType_set_38      *vdl.Type
	__VDLType_string_39   *vdl.Type
)

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true

	// Register types.
	vdl.Register((*Id)(nil))
	vdl.Register((*DevModeUpdateVClockOpts)(nil))
	vdl.Register((*BatchOptions)(nil))
	vdl.Register((*BatchHandle)(nil))
	vdl.Register((*KeyValue)(nil))
	vdl.Register((*SyncgroupSpec)(nil))
	vdl.Register((*SyncgroupMemberInfo)(nil))
	vdl.Register((*ResolverType)(nil))
	vdl.Register((*BatchSource)(nil))
	vdl.Register((*BatchInfo)(nil))
	vdl.Register((*ValueState)(nil))
	vdl.Register((*Value)(nil))
	vdl.Register((*RowOp)(nil))
	vdl.Register((*ScanOp)(nil))
	vdl.Register((*Operation)(nil))
	vdl.Register((*RowInfo)(nil))
	vdl.Register((*ConflictData)(nil))
	vdl.Register((*ConflictInfo)(nil))
	vdl.Register((*ValueSelection)(nil))
	vdl.Register((*ResolutionInfo)(nil))
	vdl.Register((*CrRule)(nil))
	vdl.Register((*CrPolicy)(nil))
	vdl.Register((*SchemaMetadata)(nil))
	vdl.Register((*BlobRef)(nil))
	vdl.Register((*BlobFetchState)(nil))
	vdl.Register((*BlobFetchStatus)(nil))
	vdl.Register((*CollectionRowPattern)(nil))
	vdl.Register((*StoreChange)(nil))
	vdl.Register((*StoreChangeCollectionInfo)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*Id)(nil)).Elem()
	__VDLType_struct_2 = vdl.TypeOf((*DevModeUpdateVClockOpts)(nil)).Elem()
	__VDLType_struct_3 = vdl.TypeOf((*vdltime.Time)(nil)).Elem()
	__VDLType_struct_4 = vdl.TypeOf((*vdltime.Duration)(nil)).Elem()
	__VDLType_struct_5 = vdl.TypeOf((*BatchOptions)(nil)).Elem()
	__VDLType_string_6 = vdl.TypeOf((*BatchHandle)(nil))
	__VDLType_struct_7 = vdl.TypeOf((*KeyValue)(nil)).Elem()
	__VDLType_struct_8 = vdl.TypeOf((*SyncgroupSpec)(nil)).Elem()
	__VDLType_map_9 = vdl.TypeOf((*access.Permissions)(nil))
	__VDLType_list_10 = vdl.TypeOf((*[]Id)(nil))
	__VDLType_list_11 = vdl.TypeOf((*[]string)(nil))
	__VDLType_struct_12 = vdl.TypeOf((*SyncgroupMemberInfo)(nil)).Elem()
	__VDLType_enum_13 = vdl.TypeOf((*ResolverType)(nil))
	__VDLType_enum_14 = vdl.TypeOf((*BatchSource)(nil))
	__VDLType_struct_15 = vdl.TypeOf((*BatchInfo)(nil)).Elem()
	__VDLType_enum_16 = vdl.TypeOf((*ValueState)(nil))
	__VDLType_struct_17 = vdl.TypeOf((*Value)(nil)).Elem()
	__VDLType_struct_18 = vdl.TypeOf((*RowOp)(nil)).Elem()
	__VDLType_optional_19 = vdl.TypeOf((*Value)(nil))
	__VDLType_struct_20 = vdl.TypeOf((*ScanOp)(nil)).Elem()
	__VDLType_union_21 = vdl.TypeOf((*Operation)(nil))
	__VDLType_struct_22 = vdl.TypeOf((*RowInfo)(nil)).Elem()
	__VDLType_list_23 = vdl.TypeOf((*[]uint64)(nil))
	__VDLType_union_24 = vdl.TypeOf((*ConflictData)(nil))
	__VDLType_struct_25 = vdl.TypeOf((*ConflictInfo)(nil)).Elem()
	__VDLType_enum_26 = vdl.TypeOf((*ValueSelection)(nil))
	__VDLType_struct_27 = vdl.TypeOf((*ResolutionInfo)(nil)).Elem()
	__VDLType_struct_28 = vdl.TypeOf((*CrRule)(nil)).Elem()
	__VDLType_struct_29 = vdl.TypeOf((*CrPolicy)(nil)).Elem()
	__VDLType_list_30 = vdl.TypeOf((*[]CrRule)(nil))
	__VDLType_struct_31 = vdl.TypeOf((*SchemaMetadata)(nil)).Elem()
	__VDLType_string_32 = vdl.TypeOf((*BlobRef)(nil))
	__VDLType_enum_33 = vdl.TypeOf((*BlobFetchState)(nil))
	__VDLType_struct_34 = vdl.TypeOf((*BlobFetchStatus)(nil)).Elem()
	__VDLType_struct_35 = vdl.TypeOf((*CollectionRowPattern)(nil)).Elem()
	__VDLType_struct_36 = vdl.TypeOf((*StoreChange)(nil)).Elem()
	__VDLType_struct_37 = vdl.TypeOf((*StoreChangeCollectionInfo)(nil)).Elem()
	__VDLType_set_38 = vdl.TypeOf((*map[access.Tag]struct{})(nil))
	__VDLType_string_39 = vdl.TypeOf((*access.Tag)(nil))

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNotInDevMode.ID), "{1:}{2:} not running with --dev=true")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidName.ID), "{1:}{2:} invalid name: '{3}'{:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCorruptDatabase.ID), "{1:}{2:} database corrupt, moved to '{3}'; client must create a new database")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrUnknownBatch.ID), "{1:}{2:} unknown batch, perhaps the server restarted")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNotBoundToBatch.ID), "{1:}{2:} not bound to batch")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrReadOnlyBatch.ID), "{1:}{2:} batch is read-only")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrConcurrentBatch.ID), "{1:}{2:} concurrent batch")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBlobNotCommitted.ID), "{1:}{2:} blob is not yet committed")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrSyncgroupJoinFailed.ID), "{1:}{2:} syncgroup join failed{:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBadExecStreamHeader.ID), "{1:}{2:} Exec stream header improperly formatted")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidPermissionsChange.ID), "{1:}{2:} the sequence of permission changes is invalid")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrUnauthorizedCreateId.ID), "{1:}{2:} not authorized to create object with id blessing '{3}' (name '{4}'){:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInferAppBlessingFailed.ID), "{1:}{2:} failed to infer app blessing pattern for {3} '{4}'{:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInferUserBlessingFailed.ID), "{1:}{2:} failed to infer user blessing pattern for {3} '{4}'{:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInferDefaultPermsFailed.ID), "{1:}{2:} failed to infer default perms for user for {3} '{4}'{:_}")

	return struct{}{}
}
