// 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":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Blessing = value
			}
		case "Name":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Name = value
			}
		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":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.NtpHost = value
			}
		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":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.DoNtpUpdate = value
			}
		case "DoLocalUpdate":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.DoLocalUpdate = value
			}
		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":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Hint = value
			}
		case "ReadOnly":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.ReadOnly = value
			}
		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 {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		*x = BatchHandle(value)
	}
	return nil
}

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

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

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

func (x KeyValue) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_7); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.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":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Key = value
			}
		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
			}
		}
	}
}

// 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 (set of collectionIds) covered by this syncgroup.
	Collections []Id
	// Mount tables at which to advertise this syncgroup, for rendezvous purposes.
	// (Note that in addition to these mount tables, Syncbase also uses
	// network-neighborhood-based discovery for rendezvous.)
	// We expect most clients to specify a single mount table, but we accept an
	// array of mount tables to permit the mount table to be changed over time
	// without disruption.
	// TODO(hpucha): Figure out a convention for advertising syncgroups in the
	// mount table.
	MountTables []string
	// Specifies the privacy of this syncgroup. More specifically, specifies
	// whether blobs in this syncgroup can be served to clients presenting
	// blobrefs obtained from other syncgroups.
	IsPrivate bool
}

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

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

func (x SyncgroupSpec) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	if x.Description != "" {
		if err := enc.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.Collections) != 0 {
		if err := enc.NextField("Collections"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Collections); err != nil {
			return err
		}
	}
	if len(x.MountTables) != 0 {
		if err := enc.NextField("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 []Id) error {
	if err := enc.StartValue(__VDLType_list_10); 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_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 := 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_8); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Description":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Description = value
			}
		case "PublishSyncbaseName":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.PublishSyncbaseName = value
			}
		case "Perms":
			if err := x.Perms.VDLRead(dec); err != nil {
				return err
			}
		case "Collections":
			if err := __VDLReadAnon_list_1(dec, &x.Collections); err != nil {
				return err
			}
		case "MountTables":
			if err := __VDLReadAnon_list_2(dec, &x.MountTables); err != nil {
				return err
			}
		case "IsPrivate":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.IsPrivate = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

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

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

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

func (x SyncgroupMemberInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_12); err != nil {
		return err
	}
	if x.SyncPriority != 0 {
		if err := enc.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_12); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "SyncPriority":
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.SyncPriority = byte(value)
			}
		case "BlobDevType":
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.BlobDevType = byte(value)
			}
		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_13); 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 {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

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

const (
	BatchSourceLocal BatchSource = iota
	BatchSourceRemote
)

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

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

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

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

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

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

func (x BatchSource) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_enum_14); 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 {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

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

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

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

func (x BatchInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_15); err != nil {
		return err
	}
	if x.Id != 0 {
		if err := enc.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_15); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Id":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Id = value
			}
		case "Hint":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Hint = value
			}
		case "Source":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.Source.Set(value); 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_16); 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 {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

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

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

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

func (x Value) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_17); err != nil {
		return err
	}
	if x.State != ValueStateExists {
		if err := enc.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_17); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "State":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.State.Set(value); 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_18); 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_18); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Key = value
			}
		case "LocalValue":
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.LocalValue = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.LocalValue = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.LocalValue.VDLRead(dec); err != nil {
					return err
				}
			}
		case "RemoteValue":
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.RemoteValue = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.RemoteValue = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.RemoteValue.VDLRead(dec); err != nil {
					return err
				}
			}
		case "AncestorValue":
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.AncestorValue = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.AncestorValue = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.AncestorValue.VDLRead(dec); err != nil {
					return err
				}
			}
		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_20); 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_20); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Start":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Start = value
			}
		case "Limit":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Limit = value
			}
		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_21); 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_21); 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_21); 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_21); 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_22); 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_23); 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_22); 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_23); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]uint64, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, elem, err := dec.NextEntryValueUint(64); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			*x = append(*x, elem)
		}
	}
}

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

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

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

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

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

func (x ConflictDataBatch) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_24); err != nil {
		return err
	}
	if err := enc.NextField("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_24); 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_24); 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_25); 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_25); 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":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Continued = value
			}
		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_26); 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 {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

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

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

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

func (x ResolutionInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_27); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.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_27); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Key = value
			}
		case "Selection":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.Selection.Set(value); err != nil {
					return err
				}
			}
		case "Result":
			if err := dec.StartValue(__VDLType_optional_19); err != nil {
				return err
			}
			if dec.IsNil() {
				x.Result = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.Result = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.Result.VDLRead(dec); err != nil {
					return err
				}
			}
		case "Continued":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Continued = value
			}
		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_28); 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_28); 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":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.KeyPrefix = value
			}
		case "Type":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Type = value
			}
		case "Resolver":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.Resolver.Set(value); 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_29); 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_30); 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_29); 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_30); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]CrRule, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem CrRule
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			*x = append(*x, elem)
		}
	}
}

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

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

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

func (x SchemaMetadata) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_31); err != nil {
		return err
	}
	if x.Version != 0 {
		if err := enc.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_31); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Version":
			switch value, err := dec.ReadValueInt(32); {
			case err != nil:
				return err
			default:
				x.Version = int32(value)
			}
		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_32); 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 {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		*x = BlobRef(value)
	}
	return nil
}

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

const (
	BlobFetchStatePending BlobFetchState = iota
	BlobFetchStateLocating
	BlobFetchStateFetching
	BlobFetchStateDone
)

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

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

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

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

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

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

func (x BlobFetchState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_enum_33); 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 {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

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

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

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

func (x BlobFetchStatus) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_34); err != nil {
		return err
	}
	if x.State != BlobFetchStatePending {
		if err := enc.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_34); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "State":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.State.Set(value); err != nil {
					return err
				}
			}
		case "Received":
			switch value, err := dec.ReadValueInt(64); {
			case err != nil:
				return err
			default:
				x.Received = value
			}
		case "Total":
			switch value, err := dec.ReadValueInt(64); {
			case err != nil:
				return err
			default:
				x.Total = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

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

func (x CollectionRowPattern) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_35); err != nil {
		return err
	}
	if x.CollectionBlessing != "" {
		if err := enc.NextField("CollectionBlessing"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.CollectionBlessing); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.CollectionName != "" {
		if err := enc.NextField("CollectionName"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.CollectionName); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.RowKey != "" {
		if err := enc.NextField("RowKey"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.RowKey); 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 *CollectionRowPattern) VDLRead(dec vdl.Decoder) error {
	*x = CollectionRowPattern{}
	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 "CollectionBlessing":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.CollectionBlessing = value
			}
		case "CollectionName":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.CollectionName = value
			}
		case "RowKey":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.RowKey = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// StoreChange is the new value for a watched entity.
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":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.FromSync = value
			}
		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. Only rows matching at least one of the patterns are
// returned. Rows in collections with no Read access are also filtered out.
//
// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
// argument that points to a particular place in the database event log. If an
// empty ResumeMarker is provided, the WatchStream will begin with a Change
// batch containing the initial state. Otherwise, the WatchStream will contain
// only changes since the provided ResumeMarker. See watch.GlobWatcher for a
// detailed explanation of the behavior.
//
// The result stream consists of a never-ending sequence of Change messages
// (until the call fails or is canceled). Each Change contains the Name field 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)
	// WatchPatterns returns a stream of changes that match any of the specified
	// patterns. At least one pattern must be specified.
	WatchPatterns(_ *context.T, resumeMarker watch.ResumeMarker, patterns []CollectionRowPattern, _ ...rpc.CallOpt) (DatabaseWatcherWatchPatternsClientCall, error)
}

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

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

type implDatabaseWatcherClientStub struct {
	name string

	watch.GlobWatcherClientStub
}

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

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

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

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

type implDatabaseWatcherWatchPatternsClientCall struct {
	rpc.ClientCall
	valRecv watch.Change
	errRecv error
}

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

type implDatabaseWatcherWatchPatternsClientCallRecv struct {
	c *implDatabaseWatcherWatchPatternsClientCall
}

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

// DatabaseWatcherServerMethods is the interface a server writer
// implements for DatabaseWatcher.
//
// DatabaseWatcher allows a client to watch for updates to the database. For
// each watch request, the client will receive a reliable stream of watch events
// without re-ordering. Only rows matching at least one of the patterns are
// returned. Rows in collections with no Read access are also filtered out.
//
// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
// argument that points to a particular place in the database event log. If an
// empty ResumeMarker is provided, the WatchStream will begin with a Change
// batch containing the initial state. Otherwise, the WatchStream will contain
// only changes since the provided ResumeMarker. See watch.GlobWatcher for a
// detailed explanation of the behavior.
//
// The result stream consists of a never-ending sequence of Change messages
// (until the call fails or is canceled). Each Change contains the Name field 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)
	// WatchPatterns returns a stream of changes that match any of the specified
	// patterns. At least one pattern must be specified.
	WatchPatterns(_ *context.T, _ DatabaseWatcherWatchPatternsServerCall, resumeMarker watch.ResumeMarker, patterns []CollectionRowPattern) error
}

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

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

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

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

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

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

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

func (s implDatabaseWatcherServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{DatabaseWatcherDesc, watch.GlobWatcherDesc}
}

// DatabaseWatcherDesc describes the DatabaseWatcher interface.
var DatabaseWatcherDesc rpc.InterfaceDesc = descDatabaseWatcher

// descDatabaseWatcher hides the desc to keep godoc clean.
var descDatabaseWatcher = rpc.InterfaceDesc{
	Name:    "DatabaseWatcher",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// DatabaseWatcher allows a client to watch for updates to the database. For\n// each watch request, the client will receive a reliable stream of watch events\n// without re-ordering. Only rows matching at least one of the patterns are\n// returned. Rows in collections with no Read access are also filtered out.\n//\n// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker\n// argument that points to a particular place in the database event log. If an\n// empty ResumeMarker is provided, the WatchStream will begin with a Change\n// batch containing the initial state. Otherwise, the WatchStream will contain\n// only changes since the provided ResumeMarker. See watch.GlobWatcher for a\n// detailed explanation of the behavior.\n//\n// The result stream consists of a never-ending sequence of Change messages\n// (until the call fails or is canceled). Each Change contains the Name field 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"))},
		},
		{
			Name: "WatchPatterns",
			Doc:  "// WatchPatterns returns a stream of changes that match any of the specified\n// patterns. At least one pattern must be specified.",
			InArgs: []rpc.ArgDesc{
				{"resumeMarker", ``}, // watch.ResumeMarker
				{"patterns", ``},     // []CollectionRowPattern
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Resolve"))},
		},
	},
}

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

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

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

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

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

type implDatabaseWatcherWatchPatternsServerCallSend struct {
	s *DatabaseWatcherWatchPatternsServerCallStub
}

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

// SyncgroupManagerClientMethods is the client interface
// containing SyncgroupManager methods.
//
// SyncgroupManager is the interface for syncgroup operations.
// 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. Only rows matching at least one of the patterns are
	// returned. Rows in collections with no Read access are also filtered out.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker. See watch.GlobWatcher for a
	// detailed explanation of the behavior.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field 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. Only rows matching at least one of the patterns are
	// returned. Rows in collections with no Read access are also filtered out.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker. See watch.GlobWatcher for a
	// detailed explanation of the behavior.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field 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. Only rows matching at least one of the patterns are
	// returned. Rows in collections with no Read access are also filtered out.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker. See watch.GlobWatcher for a
	// detailed explanation of the behavior.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field 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. Only rows matching at least one of the patterns are\n// returned. Rows in collections with no Read access are also filtered out.\n//\n// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker\n// argument that points to a particular place in the database event log. If an\n// empty ResumeMarker is provided, the WatchStream will begin with a Change\n// batch containing the initial state. Otherwise, the WatchStream will contain\n// only changes since the provided ResumeMarker. See watch.GlobWatcher for a\n// detailed explanation of the behavior.\n//\n// The result stream consists of a never-ending sequence of Change messages\n// (until the call fails or is canceled). Each Change contains the Name field 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_map_9       *vdl.Type
	__VDLType_list_10     *vdl.Type
	__VDLType_list_11     *vdl.Type
	__VDLType_struct_12   *vdl.Type
	__VDLType_enum_13     *vdl.Type
	__VDLType_enum_14     *vdl.Type
	__VDLType_struct_15   *vdl.Type
	__VDLType_enum_16     *vdl.Type
	__VDLType_struct_17   *vdl.Type
	__VDLType_struct_18   *vdl.Type
	__VDLType_optional_19 *vdl.Type
	__VDLType_struct_20   *vdl.Type
	__VDLType_union_21    *vdl.Type
	__VDLType_struct_22   *vdl.Type
	__VDLType_list_23     *vdl.Type
	__VDLType_union_24    *vdl.Type
	__VDLType_struct_25   *vdl.Type
	__VDLType_enum_26     *vdl.Type
	__VDLType_struct_27   *vdl.Type
	__VDLType_struct_28   *vdl.Type
	__VDLType_struct_29   *vdl.Type
	__VDLType_list_30     *vdl.Type
	__VDLType_struct_31   *vdl.Type
	__VDLType_string_32   *vdl.Type
	__VDLType_enum_33     *vdl.Type
	__VDLType_struct_34   *vdl.Type
	__VDLType_struct_35   *vdl.Type
	__VDLType_struct_36   *vdl.Type
)

var __VDLInitCalled bool

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

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

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

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