// 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.
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.
// TODO(sadovsky): Maybe implement Id.String().
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.NextField("Blessing"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Blessing); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Name != "" {
		if err := enc.NextField("Name"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Name); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); 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
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Blessing":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Blessing, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Name":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Name, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// 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.NextField("NtpHost"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.NtpHost); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if !x.Now.IsZero() {
		if err := enc.NextField("Now"); 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("ElapsedTime"); 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.NextField("DoNtpUpdate"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.DoNtpUpdate); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.DoLocalUpdate {
		if err := enc.NextField("DoLocalUpdate"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.DoLocalUpdate); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); 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
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "NtpHost":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.NtpHost, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Now":
			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 "ElapsedTime":
			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 "DoNtpUpdate":
			if err := dec.StartValue(vdl.BoolType); err != nil {
				return err
			}
			var err error
			if x.DoNtpUpdate, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "DoLocalUpdate":
			if err := dec.StartValue(vdl.BoolType); err != nil {
				return err
			}
			var err error
			if x.DoLocalUpdate, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// 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.NextField("Hint"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Hint); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.ReadOnly {
		if err := enc.NextField("ReadOnly"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.ReadOnly); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); 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
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Hint":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Hint, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "ReadOnly":
			if err := dec.StartValue(vdl.BoolType); err != nil {
				return err
			}
			var err error
			if x.ReadOnly, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// 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.StartValue(__VDLType_string_6); err != nil {
		return err
	}
	if err := enc.EncodeString(string(x)); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BatchHandle) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_string_6); err != nil {
		return err
	}
	tmp, err := dec.DecodeString()
	if err != nil {
		return err
	}
	*x = BatchHandle(tmp)
	return dec.FinishValue()
}

// 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.NextField("Key"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Key); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Value != nil && !x.Value.VDLIsZero() {
		if err := enc.NextField("Value"); err != nil {
			return err
		}
		if err := x.Value.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); 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
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Value":
			x.Value = new(vom.RawBytes)
			if err := x.Value.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// CollectionRow encapsulates a collection id and row key or row prefix.
type CollectionRow struct {
	CollectionId Id
	Row          string
}

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

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

func (x CollectionRow) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	if x.CollectionId != (Id{}) {
		if err := enc.NextField("CollectionId"); err != nil {
			return err
		}
		if err := x.CollectionId.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Row != "" {
		if err := enc.NextField("Row"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Row); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CollectionRow) VDLRead(dec vdl.Decoder) error {
	*x = CollectionRow{}
	if err := dec.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "CollectionId":
			if err := x.CollectionId.VDLRead(dec); err != nil {
				return err
			}
		case "Row":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Row, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); 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 then 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.
	Perms access.Permissions
	// Data (collectionId-rowPrefix pairs) covered by this syncgroup.
	Prefixes []CollectionRow
	// 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.Prefixes) != 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_9); err != nil {
		return err
	}
	if x.Description != "" {
		if err := enc.NextField("Description"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Description); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.PublishSyncbaseName != "" {
		if err := enc.NextField("PublishSyncbaseName"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.PublishSyncbaseName); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.Perms) != 0 {
		if err := enc.NextField("Perms"); err != nil {
			return err
		}
		if err := x.Perms.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.Prefixes) != 0 {
		if err := enc.NextField("Prefixes"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Prefixes); err != nil {
			return err
		}
	}
	if len(x.MountTables) != 0 {
		if err := enc.NextField("MountTables"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.MountTables); err != nil {
			return err
		}
	}
	if x.IsPrivate {
		if err := enc.NextField("IsPrivate"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.IsPrivate); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []CollectionRow) error {
	if err := enc.StartValue(__VDLType_list_11); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := x[i].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_12); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x[i]); err != nil {
			return err
		}
		if err := enc.FinishValue(); 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_9); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Description":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Description, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "PublishSyncbaseName":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.PublishSyncbaseName, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Perms":
			if err := x.Perms.VDLRead(dec); err != nil {
				return err
			}
		case "Prefixes":
			if err := __VDLReadAnon_list_1(dec, &x.Prefixes); err != nil {
				return err
			}
		case "MountTables":
			if err := __VDLReadAnon_list_2(dec, &x.MountTables); err != nil {
				return err
			}
		case "IsPrivate":
			if err := dec.StartValue(vdl.BoolType); err != nil {
				return err
			}
			var err error
			if x.IsPrivate, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]CollectionRow) error {
	if err := dec.StartValue(__VDLType_list_11); err != nil {
		return err
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]CollectionRow, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem CollectionRow
		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_12); err != nil {
		return err
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]string, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem string
		if err := dec.StartValue(vdl.StringType); err != nil {
			return err
		}
		var err error
		if elem, err = dec.DecodeString(); err != nil {
			return err
		}
		if err := dec.FinishValue(); err != nil {
			return err
		}
		*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_13); err != nil {
		return err
	}
	if x.SyncPriority != 0 {
		if err := enc.NextField("SyncPriority"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.ByteType); err != nil {
			return err
		}
		if err := enc.EncodeUint(uint64(x.SyncPriority)); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.BlobDevType != 0 {
		if err := enc.NextField("BlobDevType"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.ByteType); err != nil {
			return err
		}
		if err := enc.EncodeUint(uint64(x.BlobDevType)); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SyncgroupMemberInfo) VDLRead(dec vdl.Decoder) error {
	*x = SyncgroupMemberInfo{}
	if err := dec.StartValue(__VDLType_struct_13); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "SyncPriority":
			if err := dec.StartValue(vdl.ByteType); err != nil {
				return err
			}
			tmp, err := dec.DecodeUint(8)
			if err != nil {
				return err
			}
			x.SyncPriority = byte(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "BlobDevType":
			if err := dec.StartValue(vdl.ByteType); err != nil {
				return err
			}
			tmp, err := dec.DecodeUint(8)
			if err != nil {
				return err
			}
			x.BlobDevType = byte(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// 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.StartValue(__VDLType_enum_14); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ResolverType) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_enum_14); err != nil {
		return err
	}
	enum, err := dec.DecodeString()
	if err != nil {
		return err
	}
	if err := x.Set(enum); err != nil {
		return err
	}
	return dec.FinishValue()
}

// 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.StartValue(__VDLType_enum_15); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BatchSource) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_enum_15); err != nil {
		return err
	}
	enum, err := dec.DecodeString()
	if err != nil {
		return err
	}
	if err := x.Set(enum); err != nil {
		return err
	}
	return dec.FinishValue()
}

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_16); err != nil {
		return err
	}
	if x.Id != 0 {
		if err := enc.NextField("Id"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.Uint64Type); err != nil {
			return err
		}
		if err := enc.EncodeUint(x.Id); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Hint != "" {
		if err := enc.NextField("Hint"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Hint); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Source != BatchSourceLocal {
		if err := enc.NextField("Source"); err != nil {
			return err
		}
		if err := x.Source.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BatchInfo) VDLRead(dec vdl.Decoder) error {
	*x = BatchInfo{}
	if err := dec.StartValue(__VDLType_struct_16); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Id":
			if err := dec.StartValue(vdl.Uint64Type); err != nil {
				return err
			}
			var err error
			if x.Id, err = dec.DecodeUint(64); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Hint":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Hint, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Source":
			if err := x.Source.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); 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.StartValue(__VDLType_enum_17); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ValueState) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_enum_17); err != nil {
		return err
	}
	enum, err := dec.DecodeString()
	if err != nil {
		return err
	}
	if err := x.Set(enum); err != nil {
		return err
	}
	return dec.FinishValue()
}

// 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_18); err != nil {
		return err
	}
	if x.State != ValueStateExists {
		if err := enc.NextField("State"); err != nil {
			return err
		}
		if err := x.State.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Bytes != nil && !x.Bytes.VDLIsZero() {
		if err := enc.NextField("Bytes"); err != nil {
			return err
		}
		if err := x.Bytes.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.WriteTs.IsZero() {
		if err := enc.NextField("WriteTs"); 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(""); 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_18); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "State":
			if err := x.State.VDLRead(dec); err != nil {
				return err
			}
		case "Bytes":
			x.Bytes = new(vom.RawBytes)
			if err := x.Bytes.VDLRead(dec); err != nil {
				return err
			}
		case "WriteTs":
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.WriteTs); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); 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_19); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.NextField("Key"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Key); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.LocalValue != nil {
		if err := enc.NextField("LocalValue"); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()

		if err := x.LocalValue.VDLWrite(enc); err != nil {
			return err
		}

	}
	if x.RemoteValue != nil {
		if err := enc.NextField("RemoteValue"); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()

		if err := x.RemoteValue.VDLWrite(enc); err != nil {
			return err
		}

	}
	if x.AncestorValue != nil {
		if err := enc.NextField("AncestorValue"); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()

		if err := x.AncestorValue.VDLWrite(enc); err != nil {
			return err
		}

	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *RowOp) VDLRead(dec vdl.Decoder) error {
	*x = RowOp{}
	if err := dec.StartValue(__VDLType_struct_19); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "LocalValue":
			if err := dec.StartValue(__VDLType_optional_20); 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 "RemoteValue":
			if err := dec.StartValue(__VDLType_optional_20); 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 "AncestorValue":
			if err := dec.StartValue(__VDLType_optional_20); 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
				}
			}
		default:
			if err := dec.SkipValue(); 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_21); err != nil {
		return err
	}
	if x.Start != "" {
		if err := enc.NextField("Start"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Start); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Limit != "" {
		if err := enc.NextField("Limit"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Limit); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ScanOp) VDLRead(dec vdl.Decoder) error {
	*x = ScanOp{}
	if err := dec.StartValue(__VDLType_struct_21); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Start":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Start, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Limit":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Limit, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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_22); err != nil {
		return err
	}
	if err := enc.NextField("Read"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

func (x OperationScan) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_22); err != nil {
		return err
	}
	if err := enc.NextField("Scan"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadOperation(dec vdl.Decoder, x *Operation) error {
	if err := dec.StartValue(__VDLType_union_22); err != nil {
		return err
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "Read":
		var field OperationRead
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "Write":
		var field OperationWrite
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "Scan":
		var field OperationScan
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "":
		return fmt.Errorf("missing field in union %T, from %v", x, dec.Type())
	default:
		return fmt.Errorf("field %q not in union %T, from %v", f, x, dec.Type())
	}
	switch f, err := dec.NextField(); {
	case err != nil:
		return err
	case f != "":
		return fmt.Errorf("extra field %q in union %T, from %v", f, 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_23); err != nil {
		return err
	}
	if x.Op != nil && !x.Op.VDLIsZero() {
		if err := enc.NextField("Op"); err != nil {
			return err
		}
		if err := x.Op.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.BatchIds) != 0 {
		if err := enc.NextField("BatchIds"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_3(enc, x.BatchIds); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_3(enc vdl.Encoder, x []uint64) error {
	if err := enc.StartValue(__VDLType_list_24); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.Uint64Type); err != nil {
			return err
		}
		if err := enc.EncodeUint(x[i]); err != nil {
			return err
		}
		if err := enc.FinishValue(); 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_23); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Op":
			if err := VDLReadOperation(dec, &x.Op); err != nil {
				return err
			}
		case "BatchIds":
			if err := __VDLReadAnon_list_3(dec, &x.BatchIds); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_3(dec vdl.Decoder, x *[]uint64) error {
	if err := dec.StartValue(__VDLType_list_24); err != nil {
		return err
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]uint64, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem uint64
		if err := dec.StartValue(vdl.Uint64Type); err != nil {
			return err
		}
		var err error
		if elem, err = dec.DecodeUint(64); err != nil {
			return err
		}
		if err := dec.FinishValue(); err != nil {
			return err
		}
		*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_25); err != nil {
		return err
	}
	if err := enc.NextField("Batch"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

func VDLReadConflictData(dec vdl.Decoder, x *ConflictData) error {
	if err := dec.StartValue(__VDLType_union_25); err != nil {
		return err
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "Batch":
		var field ConflictDataBatch
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "Row":
		var field ConflictDataRow
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "":
		return fmt.Errorf("missing field in union %T, from %v", x, dec.Type())
	default:
		return fmt.Errorf("field %q not in union %T, from %v", f, x, dec.Type())
	}
	switch f, err := dec.NextField(); {
	case err != nil:
		return err
	case f != "":
		return fmt.Errorf("extra field %q in union %T, from %v", f, 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_26); err != nil {
		return err
	}
	if x.Data != nil && !x.Data.VDLIsZero() {
		if err := enc.NextField("Data"); err != nil {
			return err
		}
		if err := x.Data.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Continued {
		if err := enc.NextField("Continued"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.Continued); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); 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_26); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Data":
			if err := VDLReadConflictData(dec, &x.Data); err != nil {
				return err
			}
		case "Continued":
			if err := dec.StartValue(vdl.BoolType); err != nil {
				return err
			}
			var err error
			if x.Continued, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// 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.StartValue(__VDLType_enum_27); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ValueSelection) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_enum_27); err != nil {
		return err
	}
	enum, err := dec.DecodeString()
	if err != nil {
		return err
	}
	if err := x.Set(enum); err != nil {
		return err
	}
	return dec.FinishValue()
}

// 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_28); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.NextField("Key"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Key); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Selection != ValueSelectionLocal {
		if err := enc.NextField("Selection"); err != nil {
			return err
		}
		if err := x.Selection.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Result != nil {
		if err := enc.NextField("Result"); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()

		if err := x.Result.VDLWrite(enc); err != nil {
			return err
		}

	}
	if x.Continued {
		if err := enc.NextField("Continued"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.Continued); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ResolutionInfo) VDLRead(dec vdl.Decoder) error {
	*x = ResolutionInfo{}
	if err := dec.StartValue(__VDLType_struct_28); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Selection":
			if err := x.Selection.VDLRead(dec); err != nil {
				return err
			}
		case "Result":
			if err := dec.StartValue(__VDLType_optional_20); 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 "Continued":
			if err := dec.StartValue(vdl.BoolType); err != nil {
				return err
			}
			var err error
			if x.Continued, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// 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_29); err != nil {
		return err
	}
	if x.CollectionId != (Id{}) {
		if err := enc.NextField("CollectionId"); err != nil {
			return err
		}
		if err := x.CollectionId.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.KeyPrefix != "" {
		if err := enc.NextField("KeyPrefix"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.KeyPrefix); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Type != "" {
		if err := enc.NextField("Type"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Type); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Resolver != ResolverTypeLastWins {
		if err := enc.NextField("Resolver"); err != nil {
			return err
		}
		if err := x.Resolver.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CrRule) VDLRead(dec vdl.Decoder) error {
	*x = CrRule{}
	if err := dec.StartValue(__VDLType_struct_29); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "CollectionId":
			if err := x.CollectionId.VDLRead(dec); err != nil {
				return err
			}
		case "KeyPrefix":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.KeyPrefix, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Type":
			if err := dec.StartValue(vdl.StringType); err != nil {
				return err
			}
			var err error
			if x.Type, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Resolver":
			if err := x.Resolver.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); 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_30); err != nil {
		return err
	}
	if len(x.Rules) != 0 {
		if err := enc.NextField("Rules"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_4(enc, x.Rules); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_4(enc vdl.Encoder, x []CrRule) error {
	if err := enc.StartValue(__VDLType_list_31); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := x[i].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_30); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Rules":
			if err := __VDLReadAnon_list_4(dec, &x.Rules); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_4(dec vdl.Decoder, x *[]CrRule) error {
	if err := dec.StartValue(__VDLType_list_31); err != nil {
		return err
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]CrRule, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		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_32); err != nil {
		return err
	}
	if x.Version != 0 {
		if err := enc.NextField("Version"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.Int32Type); err != nil {
			return err
		}
		if err := enc.EncodeInt(int64(x.Version)); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if !x.Policy.VDLIsZero() {
		if err := enc.NextField("Policy"); err != nil {
			return err
		}
		if err := x.Policy.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SchemaMetadata) VDLRead(dec vdl.Decoder) error {
	*x = SchemaMetadata{}
	if err := dec.StartValue(__VDLType_struct_32); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Version":
			if err := dec.StartValue(vdl.Int32Type); err != nil {
				return err
			}
			tmp, err := dec.DecodeInt(32)
			if err != nil {
				return err
			}
			x.Version = int32(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Policy":
			if err := x.Policy.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); 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.StartValue(__VDLType_string_33); err != nil {
		return err
	}
	if err := enc.EncodeString(string(x)); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BlobRef) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_string_33); err != nil {
		return err
	}
	tmp, err := dec.DecodeString()
	if err != nil {
		return err
	}
	*x = BlobRef(tmp)
	return dec.FinishValue()
}

// 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.StartValue(__VDLType_enum_34); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BlobFetchState) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_enum_34); err != nil {
		return err
	}
	enum, err := dec.DecodeString()
	if err != nil {
		return err
	}
	if err := x.Set(enum); err != nil {
		return err
	}
	return dec.FinishValue()
}

// 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_35); err != nil {
		return err
	}
	if x.State != BlobFetchStatePending {
		if err := enc.NextField("State"); err != nil {
			return err
		}
		if err := x.State.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Received != 0 {
		if err := enc.NextField("Received"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.Int64Type); err != nil {
			return err
		}
		if err := enc.EncodeInt(x.Received); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Total != 0 {
		if err := enc.NextField("Total"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.Int64Type); err != nil {
			return err
		}
		if err := enc.EncodeInt(x.Total); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BlobFetchStatus) VDLRead(dec vdl.Decoder) error {
	*x = BlobFetchStatus{}
	if err := dec.StartValue(__VDLType_struct_35); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "State":
			if err := x.State.VDLRead(dec); err != nil {
				return err
			}
		case "Received":
			if err := dec.StartValue(vdl.Int64Type); err != nil {
				return err
			}
			var err error
			if x.Received, err = dec.DecodeInt(64); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Total":
			if err := dec.StartValue(vdl.Int64Type); err != nil {
				return err
			}
			var err error
			if x.Total, err = dec.DecodeInt(64); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// StoreChange is the new value for a watched entity.
// TODO(rogulenko): Consider adding the Shell state.
type StoreChange struct {
	// Value is the new value for the row if the Change state equals to Exists,
	// otherwise the 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("Value"); err != nil {
			return err
		}
		if err := x.Value.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.FromSync {
		if err := enc.NextField("FromSync"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.FromSync); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); 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
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Value":
			x.Value = new(vom.RawBytes)
			if err := x.Value.VDLRead(dec); err != nil {
				return err
			}
		case "FromSync":
			if err := dec.StartValue(vdl.BoolType); err != nil {
				return err
			}
			var err error
			if x.FromSync, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

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

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

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

// ServiceClientMethods is the client interface
// containing Service methods.
//
// Service represents a Vanadium Syncbase service.
// Service.Glob operates over Database ids.
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 --dev flag to be set (in addition to Admin check).
	DevModeUpdateVClock(_ *context.T, uco DevModeUpdateVClockOpts, _ ...rpc.CallOpt) error
	// DevModeGetTime returns the current time per the Syncbase clock.
	// Requires --dev flag to be set (in addition to Admin check).
	DevModeGetTime(*context.T, ...rpc.CallOpt) (time.Time, 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
}

// ServiceServerMethods is the interface a server writer
// implements for Service.
//
// Service represents a Vanadium Syncbase service.
// Service.Glob operates over Database ids.
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 --dev flag to be set (in addition to Admin check).
	DevModeUpdateVClock(_ *context.T, _ rpc.ServerCall, uco DevModeUpdateVClockOpts) error
	// DevModeGetTime returns the current time per the Syncbase clock.
	// Requires --dev flag to be set (in addition to Admin check).
	DevModeGetTime(*context.T, rpc.ServerCall) (time.Time, 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) 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.",
	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// Requires --dev flag to be set (in addition to Admin check).",
			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// Requires --dev flag to be set (in addition to Admin check).",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // time.Time
			},
			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. See watch.GlobWatcher for a detailed explanation of the
// behavior.
// TODO(rogulenko): Currently the only supported watch patterns are
// "<collectionId>/<rowPrefix>*". Consider changing that.
//
// 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. Otherwise, the WatchStream will contain
// only changes since the provided ResumeMarker.
//
// The result stream consists of a never-ending sequence of Change messages
// (until the call fails or is canceled). Each Change contains the Name field in
// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
// type. If the client has no access to a row specified in a change, that change
// is excluded from the result stream.
//
// 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.
	GetResumeMarker(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (watch.ResumeMarker, error)
}

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

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

type implDatabaseWatcherClientStub struct {
	name string

	watch.GlobWatcherClientStub
}

func (c implDatabaseWatcherClientStub) GetResumeMarker(ctx *context.T, 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
}

// 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. See watch.GlobWatcher for a detailed explanation of the
// behavior.
// TODO(rogulenko): Currently the only supported watch patterns are
// "<collectionId>/<rowPrefix>*". Consider changing that.
//
// 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. Otherwise, the WatchStream will contain
// only changes since the provided ResumeMarker.
//
// The result stream consists of a never-ending sequence of Change messages
// (until the call fails or is canceled). Each Change contains the Name field in
// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
// type. If the client has no access to a row specified in a change, that change
// is excluded from the result stream.
//
// 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.
	GetResumeMarker(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (watch.ResumeMarker, error)
}

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

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

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

type implDatabaseWatcherServerStub struct {
	impl DatabaseWatcherServerMethods
	watch.GlobWatcherServerStub
	gs *rpc.GlobState
}

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

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. See watch.GlobWatcher for a detailed explanation of the\n// behavior.\n// TODO(rogulenko): Currently the only supported watch patterns are\n// \"<collectionId>/<rowPrefix>*\". Consider changing that.\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. Otherwise, the WatchStream will contain\n// only changes since the provided ResumeMarker.\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 in\n// the form \"<collectionId>/<rowKey>\" and the Value field of the StoreChange\n// type. If the client has no access to a row specified in a change, that change\n// is excluded from the result stream.\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.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // watch.ResumeMarker
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// SyncgroupManagerClientMethods is the client interface
// containing SyncgroupManager methods.
//
// SyncgroupManager is the interface for syncgroup operations.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncgroupManagerClientMethods interface {
	// ListSyncgroups returns the relative syncgroup ids of all syncgroups attached to
	// this database.
	ListSyncgroups(*context.T, ...rpc.CallOpt) ([]Id, error)
	// CreateSyncgroup creates a new syncgroup with the given spec.
	//
	// Requires: Client must have at least Read access on the Database; all
	// Collections specified in prefixes must exist; Client must have at least
	// Read access on each of the Collection ACLs.
	CreateSyncgroup(_ *context.T, sgId Id, spec SyncgroupSpec, myInfo SyncgroupMemberInfo, _ ...rpc.CallOpt) error
	// JoinSyncgroup joins the syncgroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	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.
	//
	// Requires: Client must have at least Read access on the Database.
	LeaveSyncgroup(_ *context.T, sgId Id, _ ...rpc.CallOpt) error
	// DestroySyncgroup destroys the syncgroup. Previously synced data will
	// continue to be available to all members.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	DestroySyncgroup(_ *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.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	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: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	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: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	SetSyncgroupSpec(_ *context.T, sgId Id, spec SyncgroupSpec, version string, _ ...rpc.CallOpt) error
	// GetSyncgroupMembers gets the info objects for members of the syncgroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	GetSyncgroupMembers(_ *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.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncgroupManagerServerMethods interface {
	// ListSyncgroups returns the relative syncgroup ids of all syncgroups attached to
	// this database.
	ListSyncgroups(*context.T, rpc.ServerCall) ([]Id, error)
	// CreateSyncgroup creates a new syncgroup with the given spec.
	//
	// Requires: Client must have at least Read access on the Database; all
	// Collections specified in prefixes must exist; Client must have at least
	// Read access on each of the Collection ACLs.
	CreateSyncgroup(_ *context.T, _ rpc.ServerCall, sgId Id, spec SyncgroupSpec, myInfo SyncgroupMemberInfo) error
	// JoinSyncgroup joins the syncgroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	JoinSyncgroup(_ *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.
	//
	// Requires: Client must have at least Read access on the Database.
	LeaveSyncgroup(_ *context.T, _ rpc.ServerCall, sgId Id) error
	// DestroySyncgroup destroys the syncgroup. Previously synced data will
	// continue to be available to all members.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	DestroySyncgroup(_ *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.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	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: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	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: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	SetSyncgroupSpec(_ *context.T, _ rpc.ServerCall, sgId Id, spec SyncgroupSpec, version string) error
	// GetSyncgroupMembers gets the info objects for members of the syncgroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	GetSyncgroupMembers(_ *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.\n// TODO(hpucha): Add blessings to create/join and add a refresh method.",
	Methods: []rpc.MethodDesc{
		{
			Name: "ListSyncgroups",
			Doc:  "// ListSyncgroups returns the relative syncgroup ids of all syncgroups attached to\n// this 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: Client must have at least Read access on the Database; all\n// Collections specified in prefixes must exist; Client must have at least\n// Read access on each of the Collection ACLs.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``},   // Id
				{"spec", ``},   // SyncgroupSpec
				{"myInfo", ``}, // SyncgroupMemberInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "JoinSyncgroup",
			Doc:  "// JoinSyncgroup joins the syncgroup.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"remoteSyncbaseName", ``},        // string
				{"expectedSyncbaseBlessings", ``}, // []string
				{"sgId", ``},                      // Id
				{"myInfo", ``},                    // SyncgroupMemberInfo
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``}, // SyncgroupSpec
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "LeaveSyncgroup",
			Doc:  "// LeaveSyncgroup leaves the syncgroup. Previously synced data will continue\n// to be available.\n//\n// Requires: Client must have at least Read access on the Database.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DestroySyncgroup",
			Doc:  "// DestroySyncgroup destroys the syncgroup. Previously synced data will\n// continue to be available to all members.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "EjectFromSyncgroup",
			Doc:  "// EjectFromSyncgroup ejects a member from the syncgroup. The ejected member\n// will not be able to sync further, but will retain any data it has already\n// synced.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``},   // Id
				{"member", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetSyncgroupSpec",
			Doc:  "// GetSyncgroupSpec gets the syncgroup spec. version allows for atomic\n// read-modify-write of the spec - see comment for SetSyncgroupSpec.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``},    // SyncgroupSpec
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "SetSyncgroupSpec",
			Doc:  "// SetSyncgroupSpec sets the syncgroup spec. version may be either empty or\n// the value from a previous Get. If not empty, Set will only succeed if the\n// current version matches the specified one.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``},    // Id
				{"spec", ``},    // SyncgroupSpec
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetSyncgroupMembers",
			Doc:  "// GetSyncgroupMembers gets the info objects for members of the syncgroup.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgId", ``}, // Id
			},
			OutArgs: []rpc.ArgDesc{
				{"members", ``}, // map[string]SyncgroupMemberInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// BlobManagerClientMethods is the client interface
// containing BlobManager methods.
//
// BlobManager is the interface for blob operations.
//
// 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.
	CreateBlob(*context.T, ...rpc.CallOpt) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) (BlobManagerPutBlobClientCall, error)
	// CommitBlob marks the blob as immutable.
	CommitBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(_ *context.T, br BlobRef, _ ...rpc.CallOpt) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	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.
	FetchBlob(_ *context.T, br BlobRef, priority uint64, _ ...rpc.CallOpt) (BlobManagerFetchBlobClientCall, error)
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	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.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(_ *context.T, _ BlobManagerPutBlobServerCall, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	CommitBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(_ *context.T, _ rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	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.
	FetchBlob(_ *context.T, _ BlobManagerFetchBlobServerCall, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	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.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(_ *context.T, _ *BlobManagerPutBlobServerCallStub, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	CommitBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(_ *context.T, _ rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	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.
	FetchBlob(_ *context.T, _ *BlobManagerFetchBlobServerCallStub, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	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.",
			OutArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "PutBlob",
			Doc:  "// PutBlob appends the byte stream to the blob.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "CommitBlob",
			Doc:  "// CommitBlob marks the blob as immutable.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "GetBlobSize",
			Doc:  "// GetBlobSize returns the count of bytes written as part of the blob\n// (committed or uncommitted).",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DeleteBlob",
			Doc:  "// DeleteBlob locally deletes the blob (committed or uncommitted).",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "GetBlob",
			Doc:  "// GetBlob returns the byte stream from a committed blob starting at offset.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},     // BlobRef
				{"offset", ``}, // int64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "FetchBlob",
			Doc:  "// FetchBlob initiates fetching a blob if not locally found. priority\n// controls the network priority of the blob. Higher priority blobs are\n// fetched before the lower priority ones. However, an ongoing blob\n// transfer is not interrupted. Status updates are streamed back to the\n// client as fetch is in progress.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},       // BlobRef
				{"priority", ``}, // uint64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "PinBlob",
			Doc:  "// PinBlob locally pins the blob so that it is not evicted.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "UnpinBlob",
			Doc:  "// UnpinBlob locally unpins the blob so that it can be evicted if needed.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "KeepBlob",
			Doc:  "// KeepBlob locally caches the blob with the specified rank. Lower\n// ranked blobs are more eagerly evicted.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},   // BlobRef
				{"rank", ``}, // uint64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

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

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

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

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

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

type implBlobManagerPutBlobServerCallRecv struct {
	s *BlobManagerPutBlobServerCallStub
}

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

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

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

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

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

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

type implBlobManagerGetBlobServerCallSend struct {
	s *BlobManagerGetBlobServerCallStub
}

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

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

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

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

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

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

type implBlobManagerFetchBlobServerCallSend struct {
	s *BlobManagerFetchBlobServerCallStub
}

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

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

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

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

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

type implConflictManagerClientStub struct {
	name string
}

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

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

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

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

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

type implConflictManagerStartConflictResolverClientCallRecv struct {
	c *implConflictManagerStartConflictResolverClientCall
}

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

type implConflictManagerStartConflictResolverClientCallSend struct {
	c *implConflictManagerStartConflictResolverClientCall
}

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

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

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

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

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

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

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

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

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

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

// descConflictManager hides the desc to keep godoc clean.
var descConflictManager = rpc.InterfaceDesc{
	Name:    "ConflictManager",
	PkgPath: "v.io/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}.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

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

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

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

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

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

type implConflictManagerStartConflictResolverServerCallRecv struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

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

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

type implConflictManagerStartConflictResolverServerCallSend struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

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

// DatabaseClientMethods is the client interface
// containing Database methods.
//
// Database represents a set of Collections. Batches, queries, syncgroups, and
// watch all operate at the Database level.
// Database.Glob operates over Collection ids.
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. See watch.GlobWatcher for a detailed explanation of the
	// behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// "<collectionId>/<rowPrefix>*". Consider changing that.
	//
	// 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. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field in
	// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
	// type. If the client has no access to a row specified in a change, that change
	// is excluded from the result stream.
	//
	// 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.
	// 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.
	// TODO(sadovsky): Specify what happens if perms is nil.
	// Create requires the caller to have Write permission at the 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.
	Destroy(*context.T, ...rpc.CallOpt) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	Exists(*context.T, ...rpc.CallOpt) (bool, error)
	// ListCollections returns an unsorted list of all Collection ids that the
	// caller is allowed to see.
	// 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.)
	// Note, the glob client library checks Resolve access on every component
	// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen
	// for other RPCs.
	// TODO(ivanpi): Resolve should be checked on all RPCs.
	// TODO(sadovsky): Maybe switch to streaming RPC.
	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.
	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.
	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.
	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.
	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.
	PauseSync(*context.T, ...rpc.CallOpt) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	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.
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. See watch.GlobWatcher for a detailed explanation of the
	// behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// "<collectionId>/<rowPrefix>*". Consider changing that.
	//
	// 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. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field in
	// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
	// type. If the client has no access to a row specified in a change, that change
	// is excluded from the result stream.
	//
	// 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.
	// 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.
	// TODO(sadovsky): Specify what happens if perms is nil.
	// Create requires the caller to have Write permission at the 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.
	Destroy(*context.T, rpc.ServerCall) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	Exists(*context.T, rpc.ServerCall) (bool, error)
	// ListCollections returns an unsorted list of all Collection ids that the
	// caller is allowed to see.
	// 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.)
	// Note, the glob client library checks Resolve access on every component
	// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen
	// for other RPCs.
	// TODO(ivanpi): Resolve should be checked on all RPCs.
	// TODO(sadovsky): Maybe switch to streaming RPC.
	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.
	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.
	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.
	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.
	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.
	PauseSync(*context.T, rpc.ServerCall) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	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. See watch.GlobWatcher for a detailed explanation of the
	// behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// "<collectionId>/<rowPrefix>*". Consider changing that.
	//
	// 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. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field in
	// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
	// type. If the client has no access to a row specified in a change, that change
	// is excluded from the result stream.
	//
	// 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.
	// 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.
	// TODO(sadovsky): Specify what happens if perms is nil.
	// Create requires the caller to have Write permission at the 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.
	Destroy(*context.T, rpc.ServerCall) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	Exists(*context.T, rpc.ServerCall) (bool, error)
	// ListCollections returns an unsorted list of all Collection ids that the
	// caller is allowed to see.
	// 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.)
	// Note, the glob client library checks Resolve access on every component
	// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen
	// for other RPCs.
	// TODO(ivanpi): Resolve should be checked on all RPCs.
	// TODO(sadovsky): Maybe switch to streaming RPC.
	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.
	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.
	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.
	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.
	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.
	PauseSync(*context.T, rpc.ServerCall) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	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.",
	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. See watch.GlobWatcher for a detailed explanation of the\n// behavior.\n// TODO(rogulenko): Currently the only supported watch patterns are\n// \"<collectionId>/<rowPrefix>*\". Consider changing that.\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. Otherwise, the WatchStream will contain\n// only changes since the provided ResumeMarker.\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 in\n// the form \"<collectionId>/<rowKey>\" and the Value field of the StoreChange\n// type. If the client has no access to a row specified in a change, that change\n// is excluded from the result stream.\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.\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.\n// TODO(sadovsky): Specify what happens if perms is nil.\n// Create requires the caller to have Write permission at the 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.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Database exists. Insufficient permissions\n// cause Exists to return false instead of an error.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Resolve"))},
		},
		{
			Name: "ListCollections",
			Doc:  "// ListCollections returns an unsorted list of all Collection ids that the\n// caller is allowed to see.\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// Note, the glob client library checks Resolve access on every component\n// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen\n// for other RPCs.\n// TODO(ivanpi): Resolve should be checked on all RPCs.\n// TODO(sadovsky): Maybe switch to streaming RPC.",
			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.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},     // BatchHandle
				{"query", ``},  // string
				{"params", ``}, // []*vom.RawBytes
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			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.",
			InArgs: []rpc.ArgDesc{
				{"bo", ``}, // BatchOptions
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			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.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Abort",
			Doc:  "// Abort notifies the server that any pending changes can be discarded.\n// It is not strictly required, but it may allow the server to release locks\n// or other resources sooner than if it was not called.\n// If the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			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.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "ResumeSync",
			Doc:  "// ResumeSync resumes sync for this database. ResumeSync is idempotent.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

// 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.
type CollectionClientMethods interface {
	// Create creates this Collection.
	// TODO(sadovsky): Specify what happens if perms is nil.
	Create(_ *context.T, bh BatchHandle, perms access.Permissions, _ ...rpc.CallOpt) error
	// Destroy destroys this Collection, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
	// Exists returns true only if this Collection exists. Insufficient
	// permissions cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	GetPermissions(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the 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.
	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.
	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.
type CollectionServerMethods interface {
	// Create creates this Collection.
	// TODO(sadovsky): Specify what happens if perms is nil.
	Create(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// Destroy destroys this Collection, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Exists returns true only if this Collection exists. Insufficient
	// permissions cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	GetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the 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.
	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.
	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.
	// TODO(sadovsky): Specify what happens if perms is nil.
	Create(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// Destroy destroys this Collection, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Exists returns true only if this Collection exists. Insufficient
	// permissions cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	GetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the 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.
	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.
	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.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Collection.\n// TODO(sadovsky): Specify what happens if perms is nil.",
			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// TODO(sadovsky): Specify what happens to syncgroups.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Collection exists. Insufficient\n// permissions cause Exists to return false instead of an error.\n// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy\n// do not exist.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Resolve"))},
		},
		{
			Name: "GetPermissions",
			Doc:  "// GetPermissions returns the current Permissions for the 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.",
			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.",
			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.",
			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. Insufficient permissions
	// cause Exists to return false instead of an error.
	// Note, Exists on Row requires read permissions, unlike higher levels of
	// hierarchy which require resolve, because Row existence usually carries
	// more information.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (bool, error)
	// Get returns the value for this Row.
	Get(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (*vom.RawBytes, error)
	// Put writes the given value for this Row.
	Put(_ *context.T, bh BatchHandle, value *vom.RawBytes, _ ...rpc.CallOpt) error
	// Delete deletes this Row.
	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. Insufficient permissions
	// cause Exists to return false instead of an error.
	// Note, Exists on Row requires read permissions, unlike higher levels of
	// hierarchy which require resolve, because Row existence usually carries
	// more information.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// Get returns the value for this Row.
	Get(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (*vom.RawBytes, error)
	// Put writes the given value for this Row.
	Put(_ *context.T, _ rpc.ServerCall, bh BatchHandle, value *vom.RawBytes) error
	// Delete deletes this Row.
	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. Insufficient permissions\n// cause Exists to return false instead of an error.\n// Note, Exists on Row requires read permissions, unlike higher levels of\n// hierarchy which require resolve, because Row existence usually carries\n// more information.\n// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy\n// do not exist.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Get",
			Doc:  "// Get returns the value for this Row.",
			InArgs: []rpc.ArgDesc{
				{"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.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"value", ``}, // *vom.RawBytes
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Row.",
			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_struct_9    *vdl.Type
	__VDLType_map_10      *vdl.Type
	__VDLType_list_11     *vdl.Type
	__VDLType_list_12     *vdl.Type
	__VDLType_struct_13   *vdl.Type
	__VDLType_enum_14     *vdl.Type
	__VDLType_enum_15     *vdl.Type
	__VDLType_struct_16   *vdl.Type
	__VDLType_enum_17     *vdl.Type
	__VDLType_struct_18   *vdl.Type
	__VDLType_struct_19   *vdl.Type
	__VDLType_optional_20 *vdl.Type
	__VDLType_struct_21   *vdl.Type
	__VDLType_union_22    *vdl.Type
	__VDLType_struct_23   *vdl.Type
	__VDLType_list_24     *vdl.Type
	__VDLType_union_25    *vdl.Type
	__VDLType_struct_26   *vdl.Type
	__VDLType_enum_27     *vdl.Type
	__VDLType_struct_28   *vdl.Type
	__VDLType_struct_29   *vdl.Type
	__VDLType_struct_30   *vdl.Type
	__VDLType_list_31     *vdl.Type
	__VDLType_struct_32   *vdl.Type
	__VDLType_string_33   *vdl.Type
	__VDLType_enum_34     *vdl.Type
	__VDLType_struct_35   *vdl.Type
	__VDLType_struct_36   *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((*CollectionRow)(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((*StoreChange)(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((*CollectionRow)(nil)).Elem()
	__VDLType_struct_9 = vdl.TypeOf((*SyncgroupSpec)(nil)).Elem()
	__VDLType_map_10 = vdl.TypeOf((*access.Permissions)(nil))
	__VDLType_list_11 = vdl.TypeOf((*[]CollectionRow)(nil))
	__VDLType_list_12 = vdl.TypeOf((*[]string)(nil))
	__VDLType_struct_13 = vdl.TypeOf((*SyncgroupMemberInfo)(nil)).Elem()
	__VDLType_enum_14 = vdl.TypeOf((*ResolverType)(nil))
	__VDLType_enum_15 = vdl.TypeOf((*BatchSource)(nil))
	__VDLType_struct_16 = vdl.TypeOf((*BatchInfo)(nil)).Elem()
	__VDLType_enum_17 = vdl.TypeOf((*ValueState)(nil))
	__VDLType_struct_18 = vdl.TypeOf((*Value)(nil)).Elem()
	__VDLType_struct_19 = vdl.TypeOf((*RowOp)(nil)).Elem()
	__VDLType_optional_20 = vdl.TypeOf((*Value)(nil))
	__VDLType_struct_21 = vdl.TypeOf((*ScanOp)(nil)).Elem()
	__VDLType_union_22 = vdl.TypeOf((*Operation)(nil))
	__VDLType_struct_23 = vdl.TypeOf((*RowInfo)(nil)).Elem()
	__VDLType_list_24 = vdl.TypeOf((*[]uint64)(nil))
	__VDLType_union_25 = vdl.TypeOf((*ConflictData)(nil))
	__VDLType_struct_26 = vdl.TypeOf((*ConflictInfo)(nil)).Elem()
	__VDLType_enum_27 = vdl.TypeOf((*ValueSelection)(nil))
	__VDLType_struct_28 = vdl.TypeOf((*ResolutionInfo)(nil)).Elem()
	__VDLType_struct_29 = vdl.TypeOf((*CrRule)(nil)).Elem()
	__VDLType_struct_30 = vdl.TypeOf((*CrPolicy)(nil)).Elem()
	__VDLType_list_31 = vdl.TypeOf((*[]CrRule)(nil))
	__VDLType_struct_32 = vdl.TypeOf((*SchemaMetadata)(nil)).Elem()
	__VDLType_string_33 = vdl.TypeOf((*BlobRef)(nil))
	__VDLType_enum_34 = vdl.TypeOf((*BlobFetchState)(nil))
	__VDLType_struct_35 = vdl.TypeOf((*BlobFetchStatus)(nil)).Elem()
	__VDLType_struct_36 = vdl.TypeOf((*StoreChange)(nil)).Elem()

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

	return struct{}{}
}
