// 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"
	"reflect"
	"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 (m *Id) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Blessing == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Blessing"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Blessing")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Blessing), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Name == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("Name"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Name")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.Name), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Id) MakeVDLTarget() vdl.Target {
	return &IdTarget{Value: m}
}

type IdTarget struct {
	Value          *Id
	blessingTarget vdl.StringTarget
	nameTarget     vdl.StringTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *IdTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*Id)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *IdTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Blessing":
		t.blessingTarget.Value = &t.Value.Blessing
		target, err := &t.blessingTarget, error(nil)
		return nil, target, err
	case "Name":
		t.nameTarget.Value = &t.Value.Name
		target, err := &t.nameTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *IdTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *IdTarget) ZeroField(name string) error {
	switch name {
	case "Blessing":
		t.Value.Blessing = ""
		return nil
	case "Name":
		t.Value.Name = ""
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *IdTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x Id) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Id)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Blessing":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Blessing, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Name":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Name, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

func (m *DevModeUpdateVClockOpts) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.NtpHost == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("NtpHost"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("NtpHost")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.NtpHost), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var wireValue5 vdltime.Time
	if err := vdltime.TimeFromNative(&wireValue5, m.Now); err != nil {
		return err
	}

	var8 := (wireValue5 == vdltime.Time{})
	if var8 {
		if err := fieldsTarget1.ZeroField("Now"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Now")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue5.FillVDLTarget(fieldTarget7, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
				return err
			}
		}
	}
	var wireValue9 vdltime.Duration
	if err := vdltime.DurationFromNative(&wireValue9, m.ElapsedTime); err != nil {
		return err
	}

	var12 := (wireValue9 == vdltime.Duration{})
	if var12 {
		if err := fieldsTarget1.ZeroField("ElapsedTime"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget10, fieldTarget11, err := fieldsTarget1.StartField("ElapsedTime")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue9.FillVDLTarget(fieldTarget11, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget10, fieldTarget11); err != nil {
				return err
			}
		}
	}
	var15 := (m.DoNtpUpdate == false)
	if var15 {
		if err := fieldsTarget1.ZeroField("DoNtpUpdate"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget13, fieldTarget14, err := fieldsTarget1.StartField("DoNtpUpdate")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget14.FromBool(bool(m.DoNtpUpdate), tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget13, fieldTarget14); err != nil {
				return err
			}
		}
	}
	var18 := (m.DoLocalUpdate == false)
	if var18 {
		if err := fieldsTarget1.ZeroField("DoLocalUpdate"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget16, fieldTarget17, err := fieldsTarget1.StartField("DoLocalUpdate")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget17.FromBool(bool(m.DoLocalUpdate), tt.NonOptional().Field(4).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget16, fieldTarget17); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *DevModeUpdateVClockOpts) MakeVDLTarget() vdl.Target {
	return &DevModeUpdateVClockOptsTarget{Value: m}
}

type DevModeUpdateVClockOptsTarget struct {
	Value               *DevModeUpdateVClockOpts
	ntpHostTarget       vdl.StringTarget
	nowTarget           vdltime.TimeTarget
	elapsedTimeTarget   vdltime.DurationTarget
	doNtpUpdateTarget   vdl.BoolTarget
	doLocalUpdateTarget vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *DevModeUpdateVClockOptsTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*DevModeUpdateVClockOpts)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *DevModeUpdateVClockOptsTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "NtpHost":
		t.ntpHostTarget.Value = &t.Value.NtpHost
		target, err := &t.ntpHostTarget, error(nil)
		return nil, target, err
	case "Now":
		t.nowTarget.Value = &t.Value.Now
		target, err := &t.nowTarget, error(nil)
		return nil, target, err
	case "ElapsedTime":
		t.elapsedTimeTarget.Value = &t.Value.ElapsedTime
		target, err := &t.elapsedTimeTarget, error(nil)
		return nil, target, err
	case "DoNtpUpdate":
		t.doNtpUpdateTarget.Value = &t.Value.DoNtpUpdate
		target, err := &t.doNtpUpdateTarget, error(nil)
		return nil, target, err
	case "DoLocalUpdate":
		t.doLocalUpdateTarget.Value = &t.Value.DoLocalUpdate
		target, err := &t.doLocalUpdateTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *DevModeUpdateVClockOptsTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *DevModeUpdateVClockOptsTarget) ZeroField(name string) error {
	switch name {
	case "NtpHost":
		t.Value.NtpHost = ""
		return nil
	case "Now":
		t.Value.Now = time.Time{}
		return nil
	case "ElapsedTime":
		t.Value.ElapsedTime = time.Duration(0)
		return nil
	case "DoNtpUpdate":
		t.Value.DoNtpUpdate = false
		return nil
	case "DoLocalUpdate":
		t.Value.DoLocalUpdate = false
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *DevModeUpdateVClockOptsTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x DevModeUpdateVClockOpts) VDLIsZero() bool {
	if x.NtpHost != "" {
		return false
	}
	if !x.Now.IsZero() {
		return false
	}
	if x.ElapsedTime != time.Duration(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(vdl.TypeOf((*DevModeUpdateVClockOpts)(nil)).Elem()); 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 != time.Duration(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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "NtpHost":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.NtpHost, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Now":
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.Now); err != nil {
				return err
			}
		case "ElapsedTime":
			var wire vdltime.Duration
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.DurationToNative(wire, &x.ElapsedTime); err != nil {
				return err
			}
		case "DoNtpUpdate":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.DoNtpUpdate, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "DoLocalUpdate":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.DoLocalUpdate, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

func (m *BatchOptions) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Hint == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Hint"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Hint")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Hint), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.ReadOnly == false)
	if var7 {
		if err := fieldsTarget1.ZeroField("ReadOnly"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("ReadOnly")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromBool(bool(m.ReadOnly), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *BatchOptions) MakeVDLTarget() vdl.Target {
	return &BatchOptionsTarget{Value: m}
}

type BatchOptionsTarget struct {
	Value          *BatchOptions
	hintTarget     vdl.StringTarget
	readOnlyTarget vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *BatchOptionsTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*BatchOptions)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *BatchOptionsTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Hint":
		t.hintTarget.Value = &t.Value.Hint
		target, err := &t.hintTarget, error(nil)
		return nil, target, err
	case "ReadOnly":
		t.readOnlyTarget.Value = &t.Value.ReadOnly
		target, err := &t.readOnlyTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *BatchOptionsTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *BatchOptionsTarget) ZeroField(name string) error {
	switch name {
	case "Hint":
		t.Value.Hint = ""
		return nil
	case "ReadOnly":
		t.Value.ReadOnly = false
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *BatchOptionsTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x BatchOptions) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BatchOptions)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Hint":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Hint, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "ReadOnly":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.ReadOnly, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

func (m *BatchHandle) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromString(string((*m)), tt); err != nil {
		return err
	}
	return nil
}

func (m *BatchHandle) MakeVDLTarget() vdl.Target {
	return &BatchHandleTarget{Value: m}
}

type BatchHandleTarget struct {
	Value *BatchHandle
	vdl.TargetBase
}

func (t *BatchHandleTarget) FromString(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*BatchHandle)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	*t.Value = BatchHandle(src)

	return nil
}

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

func (x BatchHandle) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BatchHandle)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(string(x)); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

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

func (m *KeyValue) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Key == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Key"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Key")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Key), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := m.Value == nil || (m.Value.Type.Kind() == vdl.Any && m.Value.IsNil())
	if var7 {
		if err := fieldsTarget1.ZeroField("Value"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Value")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Value.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *KeyValue) MakeVDLTarget() vdl.Target {
	return &KeyValueTarget{Value: m}
}

type KeyValueTarget struct {
	Value     *KeyValue
	keyTarget vdl.StringTarget

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *KeyValueTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*KeyValue)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *KeyValueTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Key":
		t.keyTarget.Value = &t.Value.Key
		target, err := &t.keyTarget, error(nil)
		return nil, target, err
	case "Value":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Value))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *KeyValueTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *KeyValueTarget) ZeroField(name string) error {
	switch name {
	case "Key":
		t.Value.Key = ""
		return nil
	case "Value":
		t.Value.Value = vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType))
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *KeyValueTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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(vdl.TypeOf((*KeyValue)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Value":
			if err := x.Value.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

func (m *CollectionRow) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.CollectionId == Id{})
	if var4 {
		if err := fieldsTarget1.ZeroField("CollectionId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("CollectionId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.CollectionId.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Row == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("Row"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Row")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.Row), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *CollectionRow) MakeVDLTarget() vdl.Target {
	return &CollectionRowTarget{Value: m}
}

type CollectionRowTarget struct {
	Value              *CollectionRow
	collectionIdTarget IdTarget
	rowTarget          vdl.StringTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *CollectionRowTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*CollectionRow)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *CollectionRowTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "CollectionId":
		t.collectionIdTarget.Value = &t.Value.CollectionId
		target, err := &t.collectionIdTarget, error(nil)
		return nil, target, err
	case "Row":
		t.rowTarget.Value = &t.Value.Row
		target, err := &t.rowTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *CollectionRowTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *CollectionRowTarget) ZeroField(name string) error {
	switch name {
	case "CollectionId":
		t.Value.CollectionId = Id{}
		return nil
	case "Row":
		t.Value.Row = ""
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *CollectionRowTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

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

func (x *CollectionRow) VDLRead(dec vdl.Decoder) error {
	*x = CollectionRow{}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "CollectionId":
			if err := x.CollectionId.VDLRead(dec); err != nil {
				return err
			}
		case "Row":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Row, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// SyncgroupSpec contains the specification for a syncgroup.
type SyncgroupSpec struct {
	// Human-readable description of this syncgroup.
	Description string
	// Permissions governing access to this syncgroup.
	Perms access.Permissions
	// Data (collectionId-rowPrefix pairs) covered by this syncgroup.
	Prefixes []CollectionRow
	// Mount tables at which to advertise this syncgroup, for rendezvous purposes.
	// (Note that in addition to these mount tables, Syncbase also uses
	// network-neighborhood-based discovery for rendezvous.)
	// We expect most clients to specify a single mount table, but we accept an
	// array of mount tables to permit the mount table to be changed over time
	// without disruption.
	// TODO(hpucha): Figure out a convention for advertising syncgroups in the
	// mount table.
	MountTables []string
	// Specifies the privacy of this syncgroup. More specifically, specifies
	// whether blobs in this syncgroup can be served to clients presenting
	// blobrefs obtained from other syncgroups.
	IsPrivate bool
}

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

func (m *SyncgroupSpec) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Description == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Description"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Description")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Description), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var7 bool
	if len(m.Perms) == 0 {
		var7 = true
	}
	if var7 {
		if err := fieldsTarget1.ZeroField("Perms"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Perms")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Perms.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var var10 bool
	if len(m.Prefixes) == 0 {
		var10 = true
	}
	if var10 {
		if err := fieldsTarget1.ZeroField("Prefixes"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Prefixes")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget11, err := fieldTarget9.StartList(tt.NonOptional().Field(2).Type, len(m.Prefixes))
			if err != nil {
				return err
			}
			for i, elem13 := range m.Prefixes {
				elemTarget12, err := listTarget11.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem13.FillVDLTarget(elemTarget12, tt.NonOptional().Field(2).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget11.FinishElem(elemTarget12); err != nil {
					return err
				}
			}
			if err := fieldTarget9.FinishList(listTarget11); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var var16 bool
	if len(m.MountTables) == 0 {
		var16 = true
	}
	if var16 {
		if err := fieldsTarget1.ZeroField("MountTables"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget14, fieldTarget15, err := fieldsTarget1.StartField("MountTables")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget17, err := fieldTarget15.StartList(tt.NonOptional().Field(3).Type, len(m.MountTables))
			if err != nil {
				return err
			}
			for i, elem19 := range m.MountTables {
				elemTarget18, err := listTarget17.StartElem(i)
				if err != nil {
					return err
				}
				if err := elemTarget18.FromString(string(elem19), tt.NonOptional().Field(3).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget17.FinishElem(elemTarget18); err != nil {
					return err
				}
			}
			if err := fieldTarget15.FinishList(listTarget17); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget14, fieldTarget15); err != nil {
				return err
			}
		}
	}
	var22 := (m.IsPrivate == false)
	if var22 {
		if err := fieldsTarget1.ZeroField("IsPrivate"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget20, fieldTarget21, err := fieldsTarget1.StartField("IsPrivate")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget21.FromBool(bool(m.IsPrivate), tt.NonOptional().Field(4).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget20, fieldTarget21); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *SyncgroupSpec) MakeVDLTarget() vdl.Target {
	return &SyncgroupSpecTarget{Value: m}
}

type SyncgroupSpecTarget struct {
	Value             *SyncgroupSpec
	descriptionTarget vdl.StringTarget
	permsTarget       access.PermissionsTarget
	prefixesTarget    __VDLTarget1_list
	mountTablesTarget vdl.StringSliceTarget
	isPrivateTarget   vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *SyncgroupSpecTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*SyncgroupSpec)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *SyncgroupSpecTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Description":
		t.descriptionTarget.Value = &t.Value.Description
		target, err := &t.descriptionTarget, error(nil)
		return nil, target, err
	case "Perms":
		t.permsTarget.Value = &t.Value.Perms
		target, err := &t.permsTarget, error(nil)
		return nil, target, err
	case "Prefixes":
		t.prefixesTarget.Value = &t.Value.Prefixes
		target, err := &t.prefixesTarget, error(nil)
		return nil, target, err
	case "MountTables":
		t.mountTablesTarget.Value = &t.Value.MountTables
		target, err := &t.mountTablesTarget, error(nil)
		return nil, target, err
	case "IsPrivate":
		t.isPrivateTarget.Value = &t.Value.IsPrivate
		target, err := &t.isPrivateTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *SyncgroupSpecTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *SyncgroupSpecTarget) ZeroField(name string) error {
	switch name {
	case "Description":
		t.Value.Description = ""
		return nil
	case "Perms":
		t.Value.Perms = access.Permissions(nil)
		return nil
	case "Prefixes":
		t.Value.Prefixes = []CollectionRow(nil)
		return nil
	case "MountTables":
		t.Value.MountTables = []string(nil)
		return nil
	case "IsPrivate":
		t.Value.IsPrivate = false
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *SyncgroupSpecTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// []CollectionRow
type __VDLTarget1_list struct {
	Value      *[]CollectionRow
	elemTarget CollectionRowTarget
	vdl.TargetBase
	vdl.ListTargetBase
}

func (t *__VDLTarget1_list) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {

	if ttWant := vdl.TypeOf((*[]CollectionRow)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([]CollectionRow, len)
	} else {
		*t.Value = (*t.Value)[:len]
	}
	return t, nil
}
func (t *__VDLTarget1_list) StartElem(index int) (elem vdl.Target, _ error) {
	t.elemTarget.Value = &(*t.Value)[index]
	target, err := &t.elemTarget, error(nil)
	return target, err
}
func (t *__VDLTarget1_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget1_list) FinishList(elem vdl.ListTarget) error {

	return nil
}

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

func (x SyncgroupSpec) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*SyncgroupSpec)(nil)).Elem()); 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 len(x.Perms) != 0 {
		if err := enc.NextField("Perms"); err != nil {
			return err
		}
		if err := x.Perms.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.Prefixes) != 0 {
		if err := enc.NextField("Prefixes"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Prefixes); err != nil {
			return err
		}
	}
	if len(x.MountTables) != 0 {
		if err := enc.NextField("MountTables"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.MountTables); err != nil {
			return err
		}
	}
	if x.IsPrivate {
		if err := enc.NextField("IsPrivate"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.IsPrivate); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []CollectionRow) error {
	if err := enc.StartValue(vdl.TypeOf((*[]CollectionRow)(nil))); 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(vdl.TypeOf((*[]string)(nil))); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Description":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Description, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Perms":
			if err := x.Perms.VDLRead(dec); err != nil {
				return err
			}
		case "Prefixes":
			if err := __VDLReadAnon_list_1(dec, &x.Prefixes); err != nil {
				return err
			}
		case "MountTables":
			if err := __VDLReadAnon_list_2(dec, &x.MountTables); err != nil {
				return err
			}
		case "IsPrivate":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.IsPrivate, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]CollectionRow) error {
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]CollectionRow, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem CollectionRow
		if err := elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

func __VDLReadAnon_list_2(dec vdl.Decoder, x *[]string) error {
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]string, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem string
		if err := dec.StartValue(); err != nil {
			return err
		}
		var err error
		if elem, err = dec.DecodeString(); err != nil {
			return err
		}
		if err := dec.FinishValue(); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

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

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

func (m *SyncgroupMemberInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.SyncPriority == byte(0))
	if var4 {
		if err := fieldsTarget1.ZeroField("SyncPriority"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("SyncPriority")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromUint(uint64(m.SyncPriority), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.BlobDevType == byte(0))
	if var7 {
		if err := fieldsTarget1.ZeroField("BlobDevType"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("BlobDevType")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromUint(uint64(m.BlobDevType), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *SyncgroupMemberInfo) MakeVDLTarget() vdl.Target {
	return &SyncgroupMemberInfoTarget{Value: m}
}

type SyncgroupMemberInfoTarget struct {
	Value              *SyncgroupMemberInfo
	syncPriorityTarget vdl.ByteTarget
	blobDevTypeTarget  vdl.ByteTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *SyncgroupMemberInfoTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*SyncgroupMemberInfo)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *SyncgroupMemberInfoTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "SyncPriority":
		t.syncPriorityTarget.Value = &t.Value.SyncPriority
		target, err := &t.syncPriorityTarget, error(nil)
		return nil, target, err
	case "BlobDevType":
		t.blobDevTypeTarget.Value = &t.Value.BlobDevType
		target, err := &t.blobDevTypeTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *SyncgroupMemberInfoTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *SyncgroupMemberInfoTarget) ZeroField(name string) error {
	switch name {
	case "SyncPriority":
		t.Value.SyncPriority = byte(0)
		return nil
	case "BlobDevType":
		t.Value.BlobDevType = byte(0)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *SyncgroupMemberInfoTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x SyncgroupMemberInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*SyncgroupMemberInfo)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "SyncPriority":
			if err := dec.StartValue(); err != nil {
				return err
			}
			tmp, err := dec.DecodeUint(8)
			if err != nil {
				return err
			}
			x.SyncPriority = byte(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "BlobDevType":
			if err := dec.StartValue(); err != nil {
				return err
			}
			tmp, err := dec.DecodeUint(8)
			if err != nil {
				return err
			}
			x.BlobDevType = byte(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

const (
	ResolverTypeLastWins ResolverType = iota
	ResolverTypeAppResolves
	ResolverTypeDefer
)

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

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

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

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

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

func (m *ResolverType) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *ResolverType) MakeVDLTarget() vdl.Target {
	return &ResolverTypeTarget{Value: m}
}

type ResolverTypeTarget struct {
	Value *ResolverType
	vdl.TargetBase
}

func (t *ResolverTypeTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*ResolverType)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "LastWins":
		*t.Value = 0
	case "AppResolves":
		*t.Value = 1
	case "Defer":
		*t.Value = 2
	default:
		return fmt.Errorf("label %s not in enum ResolverType", src)
	}

	return nil
}

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

func (x ResolverType) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ResolverType)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

const (
	BatchSourceLocal BatchSource = iota
	BatchSourceRemote
)

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

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

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

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

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

func (m *BatchSource) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *BatchSource) MakeVDLTarget() vdl.Target {
	return &BatchSourceTarget{Value: m}
}

type BatchSourceTarget struct {
	Value *BatchSource
	vdl.TargetBase
}

func (t *BatchSourceTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*BatchSource)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "Local":
		*t.Value = 0
	case "Remote":
		*t.Value = 1
	default:
		return fmt.Errorf("label %s not in enum BatchSource", src)
	}

	return nil
}

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

func (x BatchSource) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BatchSource)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

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

func (m *BatchInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Id == uint64(0))
	if var4 {
		if err := fieldsTarget1.ZeroField("Id"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Id")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromUint(uint64(m.Id), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Hint == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("Hint"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Hint")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.Hint), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.Source == BatchSourceLocal)
	if var10 {
		if err := fieldsTarget1.ZeroField("Source"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Source")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Source.FillVDLTarget(fieldTarget9, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *BatchInfo) MakeVDLTarget() vdl.Target {
	return &BatchInfoTarget{Value: m}
}

type BatchInfoTarget struct {
	Value        *BatchInfo
	idTarget     vdl.Uint64Target
	hintTarget   vdl.StringTarget
	sourceTarget BatchSourceTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *BatchInfoTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*BatchInfo)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *BatchInfoTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Id":
		t.idTarget.Value = &t.Value.Id
		target, err := &t.idTarget, error(nil)
		return nil, target, err
	case "Hint":
		t.hintTarget.Value = &t.Value.Hint
		target, err := &t.hintTarget, error(nil)
		return nil, target, err
	case "Source":
		t.sourceTarget.Value = &t.Value.Source
		target, err := &t.sourceTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *BatchInfoTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *BatchInfoTarget) ZeroField(name string) error {
	switch name {
	case "Id":
		t.Value.Id = uint64(0)
		return nil
	case "Hint":
		t.Value.Hint = ""
		return nil
	case "Source":
		t.Value.Source = BatchSourceLocal
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *BatchInfoTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x BatchInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BatchInfo)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Id":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Id, err = dec.DecodeUint(64); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Hint":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Hint, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Source":
			if err := x.Source.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

const (
	ValueStateExists ValueState = iota
	ValueStateNoExists
	ValueStateDeleted
	ValueStateUnknown
)

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

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

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

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

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

func (m *ValueState) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *ValueState) MakeVDLTarget() vdl.Target {
	return &ValueStateTarget{Value: m}
}

type ValueStateTarget struct {
	Value *ValueState
	vdl.TargetBase
}

func (t *ValueStateTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*ValueState)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "Exists":
		*t.Value = 0
	case "NoExists":
		*t.Value = 1
	case "Deleted":
		*t.Value = 2
	case "Unknown":
		*t.Value = 3
	default:
		return fmt.Errorf("label %s not in enum ValueState", src)
	}

	return nil
}

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

func (x ValueState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ValueState)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

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

func (m *Value) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.State == ValueStateExists)
	if var4 {
		if err := fieldsTarget1.ZeroField("State"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("State")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.State.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := m.Bytes == nil || (m.Bytes.Type.Kind() == vdl.Any && m.Bytes.IsNil())
	if var7 {
		if err := fieldsTarget1.ZeroField("Bytes"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Bytes")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Bytes.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var wireValue8 vdltime.Time
	if err := vdltime.TimeFromNative(&wireValue8, m.WriteTs); err != nil {
		return err
	}

	var11 := (wireValue8 == vdltime.Time{})
	if var11 {
		if err := fieldsTarget1.ZeroField("WriteTs"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("WriteTs")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue8.FillVDLTarget(fieldTarget10, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Value) MakeVDLTarget() vdl.Target {
	return &ValueTarget{Value: m}
}

type ValueTarget struct {
	Value       *Value
	stateTarget ValueStateTarget

	writeTsTarget vdltime.TimeTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *ValueTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*Value)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *ValueTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "State":
		t.stateTarget.Value = &t.Value.State
		target, err := &t.stateTarget, error(nil)
		return nil, target, err
	case "Bytes":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Bytes))
		return nil, target, err
	case "WriteTs":
		t.writeTsTarget.Value = &t.Value.WriteTs
		target, err := &t.writeTsTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *ValueTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *ValueTarget) ZeroField(name string) error {
	switch name {
	case "State":
		t.Value.State = ValueStateExists
		return nil
	case "Bytes":
		t.Value.Bytes = vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType))
		return nil
	case "WriteTs":
		t.Value.WriteTs = time.Time{}
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *ValueTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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(vdl.TypeOf((*Value)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "State":
			if err := x.State.VDLRead(dec); err != nil {
				return err
			}
		case "Bytes":
			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 (m *RowOp) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Key == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Key"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Key")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Key), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.LocalValue == (*Value)(nil))
	if var7 {
		if err := fieldsTarget1.ZeroField("LocalValue"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("LocalValue")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.LocalValue.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.RemoteValue == (*Value)(nil))
	if var10 {
		if err := fieldsTarget1.ZeroField("RemoteValue"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("RemoteValue")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.RemoteValue.FillVDLTarget(fieldTarget9, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var13 := (m.AncestorValue == (*Value)(nil))
	if var13 {
		if err := fieldsTarget1.ZeroField("AncestorValue"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("AncestorValue")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.AncestorValue.FillVDLTarget(fieldTarget12, tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *RowOp) MakeVDLTarget() vdl.Target {
	return &RowOpTarget{Value: m}
}

type RowOpTarget struct {
	Value               *RowOp
	keyTarget           vdl.StringTarget
	localValueTarget    __VDLTarget2_optional
	remoteValueTarget   __VDLTarget2_optional
	ancestorValueTarget __VDLTarget2_optional
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *RowOpTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*RowOp)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *RowOpTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Key":
		t.keyTarget.Value = &t.Value.Key
		target, err := &t.keyTarget, error(nil)
		return nil, target, err
	case "LocalValue":
		t.localValueTarget.Value = &t.Value.LocalValue
		target, err := &t.localValueTarget, error(nil)
		return nil, target, err
	case "RemoteValue":
		t.remoteValueTarget.Value = &t.Value.RemoteValue
		target, err := &t.remoteValueTarget, error(nil)
		return nil, target, err
	case "AncestorValue":
		t.ancestorValueTarget.Value = &t.Value.AncestorValue
		target, err := &t.ancestorValueTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *RowOpTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *RowOpTarget) ZeroField(name string) error {
	switch name {
	case "Key":
		t.Value.Key = ""
		return nil
	case "LocalValue":
		t.Value.LocalValue = (*Value)(nil)
		return nil
	case "RemoteValue":
		t.Value.RemoteValue = (*Value)(nil)
		return nil
	case "AncestorValue":
		t.Value.AncestorValue = (*Value)(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *RowOpTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// Optional Value
type __VDLTarget2_optional struct {
	Value      **Value
	elemTarget ValueTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *__VDLTarget2_optional) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if *t.Value == nil {
		*t.Value = &Value{
			Bytes: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
		}
	}
	t.elemTarget.Value = *t.Value
	target, err := &t.elemTarget, error(nil)
	if err != nil {
		return nil, err
	}
	return target.StartFields(tt)
}
func (t *__VDLTarget2_optional) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}
func (t *__VDLTarget2_optional) FromNil(tt *vdl.Type) error {
	*t.Value = (*Value)(nil)
	return nil
}

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

func (x RowOp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*RowOp)(nil)).Elem()); 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 := enc.StartValue(vdl.TypeOf((*Value)(nil)).Elem()); err != nil {
			return err
		}
		if err := x.LocalValue.VDLWrite(enc); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.RemoteValue != nil {
		if err := enc.NextField("RemoteValue"); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := enc.StartValue(vdl.TypeOf((*Value)(nil)).Elem()); err != nil {
			return err
		}
		if err := x.RemoteValue.VDLWrite(enc); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.AncestorValue != nil {
		if err := enc.NextField("AncestorValue"); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := enc.StartValue(vdl.TypeOf((*Value)(nil)).Elem()); err != nil {
			return err
		}
		if err := x.AncestorValue.VDLWrite(enc); 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 *RowOp) VDLRead(dec vdl.Decoder) error {
	*x = RowOp{}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "LocalValue":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if dec.IsNil() {
				if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x.LocalValue), dec.Type()) {
					return fmt.Errorf("incompatible optional %T, from %v", x.LocalValue, dec.Type())
				}
				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(); err != nil {
				return err
			}
			if dec.IsNil() {
				if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x.RemoteValue), dec.Type()) {
					return fmt.Errorf("incompatible optional %T, from %v", x.RemoteValue, dec.Type())
				}
				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(); err != nil {
				return err
			}
			if dec.IsNil() {
				if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x.AncestorValue), dec.Type()) {
					return fmt.Errorf("incompatible optional %T, from %v", x.AncestorValue, dec.Type())
				}
				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 (m *ScanOp) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Start == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Start"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Start")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Start), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Limit == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("Limit"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Limit")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.Limit), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *ScanOp) MakeVDLTarget() vdl.Target {
	return &ScanOpTarget{Value: m}
}

type ScanOpTarget struct {
	Value       *ScanOp
	startTarget vdl.StringTarget
	limitTarget vdl.StringTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *ScanOpTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*ScanOp)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *ScanOpTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Start":
		t.startTarget.Value = &t.Value.Start
		target, err := &t.startTarget, error(nil)
		return nil, target, err
	case "Limit":
		t.limitTarget.Value = &t.Value.Limit
		target, err := &t.limitTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *ScanOpTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *ScanOpTarget) ZeroField(name string) error {
	switch name {
	case "Start":
		t.Value.Start = ""
		return nil
	case "Limit":
		t.Value.Limit = ""
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *ScanOpTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x ScanOp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ScanOp)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Start":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Start, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Limit":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Limit, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type (
	// Operation represents any single field of the Operation union type.
	//
	// Operation represents a specific operation on a row or a set of rows that is
	// a part of the conflict.
	Operation interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the Operation union type.
		__VDLReflect(__OperationReflect)
		FillVDLTarget(vdl.Target, *vdl.Type) error
		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
		UnionTargetFactory operationTargetFactory
		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 (m OperationRead) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Read")
	if err != nil {
		return err
	}

	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m OperationRead) MakeVDLTarget() vdl.Target {
	return nil
}

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 (m OperationWrite) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Write")
	if err != nil {
		return err
	}

	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(1).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m OperationWrite) MakeVDLTarget() vdl.Target {
	return nil
}

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 (m OperationScan) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Scan")
	if err != nil {
		return err
	}

	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(2).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m OperationScan) MakeVDLTarget() vdl.Target {
	return nil
}

type OperationTarget struct {
	Value     *Operation
	fieldName string

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *OperationTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
	if ttWant := vdl.TypeOf((*Operation)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}

	return t, nil
}
func (t *OperationTarget) StartField(name string) (key, field vdl.Target, _ error) {
	t.fieldName = name
	switch name {
	case "Read":
		val := RowOp{}
		return nil, &RowOpTarget{Value: &val}, nil
	case "Write":
		val := RowOp{}
		return nil, &RowOpTarget{Value: &val}, nil
	case "Scan":
		val := ScanOp{}
		return nil, &ScanOpTarget{Value: &val}, nil
	default:
		return nil, nil, fmt.Errorf("field %s not in union v.io/v23/services/syncbase.Operation", name)
	}
}
func (t *OperationTarget) FinishField(_, fieldTarget vdl.Target) error {
	switch t.fieldName {
	case "Read":
		*t.Value = OperationRead{*(fieldTarget.(*RowOpTarget)).Value}
	case "Write":
		*t.Value = OperationWrite{*(fieldTarget.(*RowOpTarget)).Value}
	case "Scan":
		*t.Value = OperationScan{*(fieldTarget.(*ScanOpTarget)).Value}
	}
	return nil
}
func (t *OperationTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

type operationTargetFactory struct{}

func (t operationTargetFactory) VDLMakeUnionTarget(union interface{}) (vdl.Target, error) {
	if typedUnion, ok := union.(*Operation); ok {
		return &OperationTarget{Value: typedUnion}, nil
	}
	return nil, fmt.Errorf("got %T, want *Operation", union)
}

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(vdl.TypeOf((*Operation)(nil))); 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(vdl.TypeOf((*Operation)(nil))); 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(vdl.TypeOf((*Operation)(nil))); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x), dec.Type()) {
		return fmt.Errorf("incompatible union %T, from %v", x, dec.Type())
	}
	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 (m *RowInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if field, ok := m.Op.(OperationRead); ok {

		var5 := (field.Value == RowOp{})
		var4 = var5
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("Op"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Op")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			unionValue6 := m.Op
			if unionValue6 == nil {
				unionValue6 = OperationRead{}
			}
			if err := unionValue6.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var9 bool
	if len(m.BatchIds) == 0 {
		var9 = true
	}
	if var9 {
		if err := fieldsTarget1.ZeroField("BatchIds"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget7, fieldTarget8, err := fieldsTarget1.StartField("BatchIds")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget10, err := fieldTarget8.StartList(tt.NonOptional().Field(1).Type, len(m.BatchIds))
			if err != nil {
				return err
			}
			for i, elem12 := range m.BatchIds {
				elemTarget11, err := listTarget10.StartElem(i)
				if err != nil {
					return err
				}
				if err := elemTarget11.FromUint(uint64(elem12), tt.NonOptional().Field(1).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget10.FinishElem(elemTarget11); err != nil {
					return err
				}
			}
			if err := fieldTarget8.FinishList(listTarget10); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget7, fieldTarget8); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *RowInfo) MakeVDLTarget() vdl.Target {
	return &RowInfoTarget{Value: m}
}

type RowInfoTarget struct {
	Value          *RowInfo
	opTarget       OperationTarget
	batchIdsTarget __VDLTarget3_list
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *RowInfoTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*RowInfo)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *RowInfoTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Op":
		t.opTarget.Value = &t.Value.Op
		target, err := &t.opTarget, error(nil)
		return nil, target, err
	case "BatchIds":
		t.batchIdsTarget.Value = &t.Value.BatchIds
		target, err := &t.batchIdsTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *RowInfoTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *RowInfoTarget) ZeroField(name string) error {
	switch name {
	case "Op":
		t.Value.Op = Operation(OperationRead{})
		return nil
	case "BatchIds":
		t.Value.BatchIds = []uint64(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *RowInfoTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// []uint64
type __VDLTarget3_list struct {
	Value      *[]uint64
	elemTarget vdl.Uint64Target
	vdl.TargetBase
	vdl.ListTargetBase
}

func (t *__VDLTarget3_list) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {

	if ttWant := vdl.TypeOf((*[]uint64)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([]uint64, len)
	} else {
		*t.Value = (*t.Value)[:len]
	}
	return t, nil
}
func (t *__VDLTarget3_list) StartElem(index int) (elem vdl.Target, _ error) {
	t.elemTarget.Value = &(*t.Value)[index]
	target, err := &t.elemTarget, error(nil)
	return target, err
}
func (t *__VDLTarget3_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget3_list) FinishList(elem vdl.ListTarget) error {

	return nil
}

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(vdl.TypeOf((*RowInfo)(nil)).Elem()); 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(vdl.TypeOf((*[]uint64)(nil))); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]uint64, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem uint64
		if err := dec.StartValue(); err != nil {
			return err
		}
		var err error
		if elem, err = dec.DecodeUint(64); err != nil {
			return err
		}
		if err := dec.FinishValue(); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

type (
	// ConflictData represents any single field of the ConflictData union type.
	//
	// ConflictData represents a unit of conflict data sent over the stream. It
	// can either contain information about a Batch or about an operation done
	// on a row.
	ConflictData interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the ConflictData union type.
		__VDLReflect(__ConflictDataReflect)
		FillVDLTarget(vdl.Target, *vdl.Type) error
		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
		UnionTargetFactory conflictDataTargetFactory
		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 (m ConflictDataBatch) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Batch")
	if err != nil {
		return err
	}

	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m ConflictDataBatch) MakeVDLTarget() vdl.Target {
	return nil
}

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 (m ConflictDataRow) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Row")
	if err != nil {
		return err
	}

	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(1).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m ConflictDataRow) MakeVDLTarget() vdl.Target {
	return nil
}

type ConflictDataTarget struct {
	Value     *ConflictData
	fieldName string

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *ConflictDataTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
	if ttWant := vdl.TypeOf((*ConflictData)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}

	return t, nil
}
func (t *ConflictDataTarget) StartField(name string) (key, field vdl.Target, _ error) {
	t.fieldName = name
	switch name {
	case "Batch":
		val := BatchInfo{}
		return nil, &BatchInfoTarget{Value: &val}, nil
	case "Row":
		val := RowInfo{
			Op: OperationRead{},
		}
		return nil, &RowInfoTarget{Value: &val}, nil
	default:
		return nil, nil, fmt.Errorf("field %s not in union v.io/v23/services/syncbase.ConflictData", name)
	}
}
func (t *ConflictDataTarget) FinishField(_, fieldTarget vdl.Target) error {
	switch t.fieldName {
	case "Batch":
		*t.Value = ConflictDataBatch{*(fieldTarget.(*BatchInfoTarget)).Value}
	case "Row":
		*t.Value = ConflictDataRow{*(fieldTarget.(*RowInfoTarget)).Value}
	}
	return nil
}
func (t *ConflictDataTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

type conflictDataTargetFactory struct{}

func (t conflictDataTargetFactory) VDLMakeUnionTarget(union interface{}) (vdl.Target, error) {
	if typedUnion, ok := union.(*ConflictData); ok {
		return &ConflictDataTarget{Value: typedUnion}, nil
	}
	return nil, fmt.Errorf("got %T, want *ConflictData", union)
}

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(vdl.TypeOf((*ConflictData)(nil))); 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(vdl.TypeOf((*ConflictData)(nil))); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x), dec.Type()) {
		return fmt.Errorf("incompatible union %T, from %v", x, dec.Type())
	}
	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 (m *ConflictInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if field, ok := m.Data.(ConflictDataBatch); ok {

		var5 := (field.Value == BatchInfo{})
		var4 = var5
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("Data"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Data")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			unionValue6 := m.Data
			if unionValue6 == nil {
				unionValue6 = ConflictDataBatch{}
			}
			if err := unionValue6.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var9 := (m.Continued == false)
	if var9 {
		if err := fieldsTarget1.ZeroField("Continued"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget7, fieldTarget8, err := fieldsTarget1.StartField("Continued")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget8.FromBool(bool(m.Continued), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget7, fieldTarget8); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *ConflictInfo) MakeVDLTarget() vdl.Target {
	return &ConflictInfoTarget{Value: m}
}

type ConflictInfoTarget struct {
	Value           *ConflictInfo
	dataTarget      ConflictDataTarget
	continuedTarget vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *ConflictInfoTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*ConflictInfo)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *ConflictInfoTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Data":
		t.dataTarget.Value = &t.Value.Data
		target, err := &t.dataTarget, error(nil)
		return nil, target, err
	case "Continued":
		t.continuedTarget.Value = &t.Value.Continued
		target, err := &t.continuedTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *ConflictInfoTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *ConflictInfoTarget) ZeroField(name string) error {
	switch name {
	case "Data":
		t.Value.Data = ConflictData(ConflictDataBatch{})
		return nil
	case "Continued":
		t.Value.Continued = false
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *ConflictInfoTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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(vdl.TypeOf((*ConflictInfo)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Data":
			if err := VDLReadConflictData(dec, &x.Data); err != nil {
				return err
			}
		case "Continued":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Continued, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

const (
	ValueSelectionLocal ValueSelection = iota
	ValueSelectionRemote
	ValueSelectionOther
)

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

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

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

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

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

func (m *ValueSelection) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *ValueSelection) MakeVDLTarget() vdl.Target {
	return &ValueSelectionTarget{Value: m}
}

type ValueSelectionTarget struct {
	Value *ValueSelection
	vdl.TargetBase
}

func (t *ValueSelectionTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*ValueSelection)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "Local":
		*t.Value = 0
	case "Remote":
		*t.Value = 1
	case "Other":
		*t.Value = 2
	default:
		return fmt.Errorf("label %s not in enum ValueSelection", src)
	}

	return nil
}

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

func (x ValueSelection) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ValueSelection)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

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

func (m *ResolutionInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Key == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Key"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Key")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Key), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Selection == ValueSelectionLocal)
	if var7 {
		if err := fieldsTarget1.ZeroField("Selection"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Selection")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Selection.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.Result == (*Value)(nil))
	if var10 {
		if err := fieldsTarget1.ZeroField("Result"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Result")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Result.FillVDLTarget(fieldTarget9, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var13 := (m.Continued == false)
	if var13 {
		if err := fieldsTarget1.ZeroField("Continued"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("Continued")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget12.FromBool(bool(m.Continued), tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *ResolutionInfo) MakeVDLTarget() vdl.Target {
	return &ResolutionInfoTarget{Value: m}
}

type ResolutionInfoTarget struct {
	Value           *ResolutionInfo
	keyTarget       vdl.StringTarget
	selectionTarget ValueSelectionTarget
	resultTarget    __VDLTarget2_optional
	continuedTarget vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *ResolutionInfoTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*ResolutionInfo)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *ResolutionInfoTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Key":
		t.keyTarget.Value = &t.Value.Key
		target, err := &t.keyTarget, error(nil)
		return nil, target, err
	case "Selection":
		t.selectionTarget.Value = &t.Value.Selection
		target, err := &t.selectionTarget, error(nil)
		return nil, target, err
	case "Result":
		t.resultTarget.Value = &t.Value.Result
		target, err := &t.resultTarget, error(nil)
		return nil, target, err
	case "Continued":
		t.continuedTarget.Value = &t.Value.Continued
		target, err := &t.continuedTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *ResolutionInfoTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *ResolutionInfoTarget) ZeroField(name string) error {
	switch name {
	case "Key":
		t.Value.Key = ""
		return nil
	case "Selection":
		t.Value.Selection = ValueSelectionLocal
		return nil
	case "Result":
		t.Value.Result = (*Value)(nil)
		return nil
	case "Continued":
		t.Value.Continued = false
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *ResolutionInfoTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x ResolutionInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ResolutionInfo)(nil)).Elem()); 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 := enc.StartValue(vdl.TypeOf((*Value)(nil)).Elem()); err != nil {
			return err
		}
		if err := x.Result.VDLWrite(enc); err != nil {
			return err
		}
		if err := enc.FinishValue(); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Key":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Selection":
			if err := x.Selection.VDLRead(dec); err != nil {
				return err
			}
		case "Result":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if dec.IsNil() {
				if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x.Result), dec.Type()) {
					return fmt.Errorf("incompatible optional %T, from %v", x.Result, dec.Type())
				}
				x.Result = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.Result = new(Value)
				dec.IgnoreNextStartValue()
				if err := x.Result.VDLRead(dec); err != nil {
					return err
				}
			}
		case "Continued":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Continued, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

func (m *CrRule) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.CollectionId == Id{})
	if var4 {
		if err := fieldsTarget1.ZeroField("CollectionId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("CollectionId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.CollectionId.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.KeyPrefix == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("KeyPrefix"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("KeyPrefix")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.KeyPrefix), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.Type == "")
	if var10 {
		if err := fieldsTarget1.ZeroField("Type"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Type")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget9.FromString(string(m.Type), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var13 := (m.Resolver == ResolverTypeLastWins)
	if var13 {
		if err := fieldsTarget1.ZeroField("Resolver"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("Resolver")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Resolver.FillVDLTarget(fieldTarget12, tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *CrRule) MakeVDLTarget() vdl.Target {
	return &CrRuleTarget{Value: m}
}

type CrRuleTarget struct {
	Value              *CrRule
	collectionIdTarget IdTarget
	keyPrefixTarget    vdl.StringTarget
	typeTarget         vdl.StringTarget
	resolverTarget     ResolverTypeTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *CrRuleTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*CrRule)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *CrRuleTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "CollectionId":
		t.collectionIdTarget.Value = &t.Value.CollectionId
		target, err := &t.collectionIdTarget, error(nil)
		return nil, target, err
	case "KeyPrefix":
		t.keyPrefixTarget.Value = &t.Value.KeyPrefix
		target, err := &t.keyPrefixTarget, error(nil)
		return nil, target, err
	case "Type":
		t.typeTarget.Value = &t.Value.Type
		target, err := &t.typeTarget, error(nil)
		return nil, target, err
	case "Resolver":
		t.resolverTarget.Value = &t.Value.Resolver
		target, err := &t.resolverTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *CrRuleTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *CrRuleTarget) ZeroField(name string) error {
	switch name {
	case "CollectionId":
		t.Value.CollectionId = Id{}
		return nil
	case "KeyPrefix":
		t.Value.KeyPrefix = ""
		return nil
	case "Type":
		t.Value.Type = ""
		return nil
	case "Resolver":
		t.Value.Resolver = ResolverTypeLastWins
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *CrRuleTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x CrRule) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*CrRule)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "CollectionId":
			if err := x.CollectionId.VDLRead(dec); err != nil {
				return err
			}
		case "KeyPrefix":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.KeyPrefix, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Type":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Type, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Resolver":
			if err := x.Resolver.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

func (m *CrPolicy) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.Rules) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("Rules"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Rules")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget5, err := fieldTarget3.StartList(tt.NonOptional().Field(0).Type, len(m.Rules))
			if err != nil {
				return err
			}
			for i, elem7 := range m.Rules {
				elemTarget6, err := listTarget5.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem7.FillVDLTarget(elemTarget6, tt.NonOptional().Field(0).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget5.FinishElem(elemTarget6); err != nil {
					return err
				}
			}
			if err := fieldTarget3.FinishList(listTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *CrPolicy) MakeVDLTarget() vdl.Target {
	return &CrPolicyTarget{Value: m}
}

type CrPolicyTarget struct {
	Value       *CrPolicy
	rulesTarget __VDLTarget4_list
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *CrPolicyTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*CrPolicy)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *CrPolicyTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Rules":
		t.rulesTarget.Value = &t.Value.Rules
		target, err := &t.rulesTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *CrPolicyTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *CrPolicyTarget) ZeroField(name string) error {
	switch name {
	case "Rules":
		t.Value.Rules = []CrRule(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *CrPolicyTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// []CrRule
type __VDLTarget4_list struct {
	Value      *[]CrRule
	elemTarget CrRuleTarget
	vdl.TargetBase
	vdl.ListTargetBase
}

func (t *__VDLTarget4_list) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {

	if ttWant := vdl.TypeOf((*[]CrRule)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([]CrRule, len)
	} else {
		*t.Value = (*t.Value)[:len]
	}
	return t, nil
}
func (t *__VDLTarget4_list) StartElem(index int) (elem vdl.Target, _ error) {
	t.elemTarget.Value = &(*t.Value)[index]
	target, err := &t.elemTarget, error(nil)
	return target, err
}
func (t *__VDLTarget4_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget4_list) FinishList(elem vdl.ListTarget) error {

	return nil
}

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(vdl.TypeOf((*CrPolicy)(nil)).Elem()); 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(vdl.TypeOf((*[]CrRule)(nil))); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]CrRule, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem CrRule
		if err := elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

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

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

func (m *SchemaMetadata) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Version == int32(0))
	if var4 {
		if err := fieldsTarget1.ZeroField("Version"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Version")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromInt(int64(m.Version), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := true
	var var8 bool
	if len(m.Policy.Rules) == 0 {
		var8 = true
	}
	var7 = var7 && var8
	if var7 {
		if err := fieldsTarget1.ZeroField("Policy"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Policy")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Policy.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *SchemaMetadata) MakeVDLTarget() vdl.Target {
	return &SchemaMetadataTarget{Value: m}
}

type SchemaMetadataTarget struct {
	Value         *SchemaMetadata
	versionTarget vdl.Int32Target
	policyTarget  CrPolicyTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *SchemaMetadataTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*SchemaMetadata)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *SchemaMetadataTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Version":
		t.versionTarget.Value = &t.Value.Version
		target, err := &t.versionTarget, error(nil)
		return nil, target, err
	case "Policy":
		t.policyTarget.Value = &t.Value.Policy
		target, err := &t.policyTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *SchemaMetadataTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *SchemaMetadataTarget) ZeroField(name string) error {
	switch name {
	case "Version":
		t.Value.Version = int32(0)
		return nil
	case "Policy":
		t.Value.Policy = CrPolicy{}
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *SchemaMetadataTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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(vdl.TypeOf((*SchemaMetadata)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Version":
			if err := dec.StartValue(); err != nil {
				return err
			}
			tmp, err := dec.DecodeInt(32)
			if err != nil {
				return err
			}
			x.Version = int32(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Policy":
			if err := x.Policy.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

func (m *BlobRef) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromString(string((*m)), tt); err != nil {
		return err
	}
	return nil
}

func (m *BlobRef) MakeVDLTarget() vdl.Target {
	return &BlobRefTarget{Value: m}
}

type BlobRefTarget struct {
	Value *BlobRef
	vdl.TargetBase
}

func (t *BlobRefTarget) FromString(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*BlobRef)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	*t.Value = BlobRef(src)

	return nil
}

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

func (x BlobRef) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BlobRef)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(string(x)); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

const (
	BlobFetchStatePending BlobFetchState = iota
	BlobFetchStateLocating
	BlobFetchStateFetching
	BlobFetchStateDone
)

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

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

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

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

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

func (m *BlobFetchState) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *BlobFetchState) MakeVDLTarget() vdl.Target {
	return &BlobFetchStateTarget{Value: m}
}

type BlobFetchStateTarget struct {
	Value *BlobFetchState
	vdl.TargetBase
}

func (t *BlobFetchStateTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*BlobFetchState)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "Pending":
		*t.Value = 0
	case "Locating":
		*t.Value = 1
	case "Fetching":
		*t.Value = 2
	case "Done":
		*t.Value = 3
	default:
		return fmt.Errorf("label %s not in enum BlobFetchState", src)
	}

	return nil
}

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

func (x BlobFetchState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BlobFetchState)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

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

func (m *BlobFetchStatus) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.State == BlobFetchStatePending)
	if var4 {
		if err := fieldsTarget1.ZeroField("State"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("State")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.State.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Received == int64(0))
	if var7 {
		if err := fieldsTarget1.ZeroField("Received"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Received")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromInt(int64(m.Received), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.Total == int64(0))
	if var10 {
		if err := fieldsTarget1.ZeroField("Total"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Total")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget9.FromInt(int64(m.Total), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *BlobFetchStatus) MakeVDLTarget() vdl.Target {
	return &BlobFetchStatusTarget{Value: m}
}

type BlobFetchStatusTarget struct {
	Value          *BlobFetchStatus
	stateTarget    BlobFetchStateTarget
	receivedTarget vdl.Int64Target
	totalTarget    vdl.Int64Target
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *BlobFetchStatusTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*BlobFetchStatus)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *BlobFetchStatusTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "State":
		t.stateTarget.Value = &t.Value.State
		target, err := &t.stateTarget, error(nil)
		return nil, target, err
	case "Received":
		t.receivedTarget.Value = &t.Value.Received
		target, err := &t.receivedTarget, error(nil)
		return nil, target, err
	case "Total":
		t.totalTarget.Value = &t.Value.Total
		target, err := &t.totalTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *BlobFetchStatusTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *BlobFetchStatusTarget) ZeroField(name string) error {
	switch name {
	case "State":
		t.Value.State = BlobFetchStatePending
		return nil
	case "Received":
		t.Value.Received = int64(0)
		return nil
	case "Total":
		t.Value.Total = int64(0)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *BlobFetchStatusTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x BlobFetchStatus) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BlobFetchStatus)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "State":
			if err := x.State.VDLRead(dec); err != nil {
				return err
			}
		case "Received":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Received, err = dec.DecodeInt(64); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Total":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Total, err = dec.DecodeInt(64); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// StoreChange is the new value for a watched entity.
// TODO(rogulenko): Consider adding the Shell state.
type StoreChange struct {
	// Value is the new value for the row if the Change state equals to Exists,
	// otherwise the Value is nil.
	Value *vom.RawBytes
	// FromSync indicates whether the change came from sync. If FromSync is
	// false, then the change originated from the local device.
	// Note: FromSync is always false for initial state Changes.
	FromSync bool
}

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

func (m *StoreChange) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := m.Value == nil || (m.Value.Type.Kind() == vdl.Any && m.Value.IsNil())
	if var4 {
		if err := fieldsTarget1.ZeroField("Value"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Value")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.FromSync == false)
	if var7 {
		if err := fieldsTarget1.ZeroField("FromSync"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("FromSync")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromBool(bool(m.FromSync), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *StoreChange) MakeVDLTarget() vdl.Target {
	return &StoreChangeTarget{Value: m}
}

type StoreChangeTarget struct {
	Value *StoreChange

	fromSyncTarget vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *StoreChangeTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*StoreChange)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *StoreChangeTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Value":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Value))
		return nil, target, err
	case "FromSync":
		t.fromSyncTarget.Value = &t.Value.FromSync
		target, err := &t.fromSyncTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *StoreChangeTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *StoreChangeTarget) ZeroField(name string) error {
	switch name {
	case "Value":
		t.Value.Value = vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType))
		return nil
	case "FromSync":
		t.Value.FromSync = false
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *StoreChangeTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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(vdl.TypeOf((*StoreChange)(nil)).Elem()); 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(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Value":
			if err := x.Value.VDLRead(dec); err != nil {
				return err
			}
		case "FromSync":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.FromSync, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

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

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

var (
	ErrNotInDevMode        = verror.Register("v.io/v23/services/syncbase.NotInDevMode", verror.NoRetry, "{1:}{2:} not running with --dev=true")
	ErrInvalidName         = verror.Register("v.io/v23/services/syncbase.InvalidName", verror.NoRetry, "{1:}{2:} invalid name: {3}")
	ErrCorruptDatabase     = verror.Register("v.io/v23/services/syncbase.CorruptDatabase", verror.NoRetry, "{1:}{2:} database corrupt, moved to {3}; client must create a new database")
	ErrUnknownBatch        = verror.Register("v.io/v23/services/syncbase.UnknownBatch", verror.NoRetry, "{1:}{2:} unknown batch, perhaps the server restarted")
	ErrNotBoundToBatch     = verror.Register("v.io/v23/services/syncbase.NotBoundToBatch", verror.NoRetry, "{1:}{2:} not bound to batch")
	ErrReadOnlyBatch       = verror.Register("v.io/v23/services/syncbase.ReadOnlyBatch", verror.NoRetry, "{1:}{2:} batch is read-only")
	ErrConcurrentBatch     = verror.Register("v.io/v23/services/syncbase.ConcurrentBatch", verror.NoRetry, "{1:}{2:} concurrent batch")
	ErrBlobNotCommitted    = verror.Register("v.io/v23/services/syncbase.BlobNotCommitted", verror.NoRetry, "{1:}{2:} blob is not yet committed")
	ErrSyncgroupJoinFailed = verror.Register("v.io/v23/services/syncbase.SyncgroupJoinFailed", verror.NoRetry, "{1:}{2:} syncgroup join failed")
	ErrBadExecStreamHeader = verror.Register("v.io/v23/services/syncbase.BadExecStreamHeader", verror.NoRetry, "{1:}{2:} Exec stream header improperly formatted")
)

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

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

// ServiceClientMethods is the client interface
// containing Service methods.
//
// Service represents a Vanadium Syncbase service.
// Service.Glob operates over Database ids.
type ServiceClientMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectClientMethods
	// DevModeUpdateVClock updates various bits of Syncbase virtual clock and
	// clock daemon state based on the specified options.
	// Requires --dev flag to be set (in addition to Admin check).
	DevModeUpdateVClock(_ *context.T, uco DevModeUpdateVClockOpts, _ ...rpc.CallOpt) error
	// DevModeGetTime returns the current time per the Syncbase clock.
	// Requires --dev flag to be set (in addition to Admin check).
	DevModeGetTime(*context.T, ...rpc.CallOpt) (time.Time, error)
}

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

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

type implServiceClientStub struct {
	name string

	permissions.ObjectClientStub
}

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

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

// ServiceServerMethods is the interface a server writer
// implements for Service.
//
// Service represents a Vanadium Syncbase service.
// Service.Glob operates over Database ids.
type ServiceServerMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerMethods
	// DevModeUpdateVClock updates various bits of Syncbase virtual clock and
	// clock daemon state based on the specified options.
	// Requires --dev flag to be set (in addition to Admin check).
	DevModeUpdateVClock(_ *context.T, _ rpc.ServerCall, uco DevModeUpdateVClockOpts) error
	// DevModeGetTime returns the current time per the Syncbase clock.
	// Requires --dev flag to be set (in addition to Admin check).
	DevModeGetTime(*context.T, rpc.ServerCall) (time.Time, error)
}

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

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

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

type implServiceServerStub struct {
	impl ServiceServerMethods
	permissions.ObjectServerStub
	gs *rpc.GlobState
}

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

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

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

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

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

// descService hides the desc to keep godoc clean.
var descService = rpc.InterfaceDesc{
	Name:    "Service",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Service represents a Vanadium Syncbase service.\n// Service.Glob operates over Database ids.",
	Embeds: []rpc.EmbedDesc{
		{"Object", "v.io/v23/services/permissions", "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "DevModeUpdateVClock",
			Doc:  "// DevModeUpdateVClock updates various bits of Syncbase virtual clock and\n// clock daemon state based on the specified options.\n// Requires --dev flag to be set (in addition to Admin check).",
			InArgs: []rpc.ArgDesc{
				{"uco", ``}, // DevModeUpdateVClockOpts
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "DevModeGetTime",
			Doc:  "// DevModeGetTime returns the current time per the Syncbase clock.\n// Requires --dev flag to be set (in addition to Admin check).",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // time.Time
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
	},
}

// DatabaseWatcherClientMethods is the client interface
// containing DatabaseWatcher methods.
//
// DatabaseWatcher allows a client to watch for updates to the database. For
// each watch request, the client will receive a reliable stream of watch events
// without re-ordering. See watch.GlobWatcher for a detailed explanation of the
// behavior.
// TODO(rogulenko): Currently the only supported watch patterns are
// "<collectionId>/<rowPrefix>*". Consider changing that.
//
// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
// argument that points to a particular place in the database event log. If an
// empty ResumeMarker is provided, the WatchStream will begin with a Change
// batch containing the initial state. Otherwise, the WatchStream will contain
// only changes since the provided ResumeMarker.
//
// The result stream consists of a never-ending sequence of Change messages
// (until the call fails or is canceled). Each Change contains the Name field in
// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
// type. If the client has no access to a row specified in a change, that change
// is excluded from the result stream.
//
// Note: A single Watch Change batch may contain changes from more than one
// batch as originally committed on a remote Syncbase or obtained from conflict
// resolution. However, changes from a single original batch will always appear
// in the same Change batch.
type DatabaseWatcherClientMethods interface {
	// GlobWatcher allows a client to receive updates for changes to objects
	// that match a pattern.  See the package comments for details.
	watch.GlobWatcherClientMethods
	// GetResumeMarker returns the ResumeMarker that points to the current end
	// of the event log. GetResumeMarker() can be called on a batch.
	GetResumeMarker(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (watch.ResumeMarker, error)
}

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

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

type implDatabaseWatcherClientStub struct {
	name string

	watch.GlobWatcherClientStub
}

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

// DatabaseWatcherServerMethods is the interface a server writer
// implements for DatabaseWatcher.
//
// DatabaseWatcher allows a client to watch for updates to the database. For
// each watch request, the client will receive a reliable stream of watch events
// without re-ordering. See watch.GlobWatcher for a detailed explanation of the
// behavior.
// TODO(rogulenko): Currently the only supported watch patterns are
// "<collectionId>/<rowPrefix>*". Consider changing that.
//
// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
// argument that points to a particular place in the database event log. If an
// empty ResumeMarker is provided, the WatchStream will begin with a Change
// batch containing the initial state. Otherwise, the WatchStream will contain
// only changes since the provided ResumeMarker.
//
// The result stream consists of a never-ending sequence of Change messages
// (until the call fails or is canceled). Each Change contains the Name field in
// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
// type. If the client has no access to a row specified in a change, that change
// is excluded from the result stream.
//
// Note: A single Watch Change batch may contain changes from more than one
// batch as originally committed on a remote Syncbase or obtained from conflict
// resolution. However, changes from a single original batch will always appear
// in the same Change batch.
type DatabaseWatcherServerMethods interface {
	// GlobWatcher allows a client to receive updates for changes to objects
	// that match a pattern.  See the package comments for details.
	watch.GlobWatcherServerMethods
	// GetResumeMarker returns the ResumeMarker that points to the current end
	// of the event log. GetResumeMarker() can be called on a batch.
	GetResumeMarker(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (watch.ResumeMarker, error)
}

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

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

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

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

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

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

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

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

// descDatabaseWatcher hides the desc to keep godoc clean.
var descDatabaseWatcher = rpc.InterfaceDesc{
	Name:    "DatabaseWatcher",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// DatabaseWatcher allows a client to watch for updates to the database. For\n// each watch request, the client will receive a reliable stream of watch events\n// without re-ordering. See watch.GlobWatcher for a detailed explanation of the\n// behavior.\n// TODO(rogulenko): Currently the only supported watch patterns are\n// \"<collectionId>/<rowPrefix>*\". Consider changing that.\n//\n// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker\n// argument that points to a particular place in the database event log. If an\n// empty ResumeMarker is provided, the WatchStream will begin with a Change\n// batch containing the initial state. Otherwise, the WatchStream will contain\n// only changes since the provided ResumeMarker.\n//\n// The result stream consists of a never-ending sequence of Change messages\n// (until the call fails or is canceled). Each Change contains the Name field in\n// the form \"<collectionId>/<rowKey>\" and the Value field of the StoreChange\n// type. If the client has no access to a row specified in a change, that change\n// is excluded from the result stream.\n//\n// Note: A single Watch Change batch may contain changes from more than one\n// batch as originally committed on a remote Syncbase or obtained from conflict\n// resolution. However, changes from a single original batch will always appear\n// in the same Change batch.",
	Embeds: []rpc.EmbedDesc{
		{"GlobWatcher", "v.io/v23/services/watch", "// GlobWatcher allows a client to receive updates for changes to objects\n// that match a pattern.  See the package comments for details."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "GetResumeMarker",
			Doc:  "// GetResumeMarker returns the ResumeMarker that points to the current end\n// of the event log. GetResumeMarker() can be called on a batch.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // watch.ResumeMarker
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// SyncgroupManagerClientMethods is the client interface
// containing SyncgroupManager methods.
//
// SyncgroupManager is the interface for syncgroup operations.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncgroupManagerClientMethods interface {
	// GetSyncgroupNames returns the global names of all syncgroups attached to
	// this database.
	GetSyncgroupNames(*context.T, ...rpc.CallOpt) ([]string, error)
	// CreateSyncgroup creates a new syncgroup with the given spec.
	//
	// Requires: Client must have at least Read access on the Database; all
	// Collections specified in prefixes must exist; Client must have at least
	// Read access on each of the Collection ACLs.
	CreateSyncgroup(_ *context.T, sgName string, 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, sgName string, 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, sgName string, _ ...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, sgName string, _ ...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, sgName string, 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, sgName string, _ ...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, sgName string, 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, sgName string, _ ...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) GetSyncgroupNames(ctx *context.T, opts ...rpc.CallOpt) (o0 []string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetSyncgroupNames", nil, []interface{}{&o0}, opts...)
	return
}

func (c implSyncgroupManagerClientStub) CreateSyncgroup(ctx *context.T, i0 string, i1 SyncgroupSpec, i2 SyncgroupMemberInfo, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "CreateSyncgroup", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

func (c implSyncgroupManagerClientStub) JoinSyncgroup(ctx *context.T, i0 string, i1 SyncgroupMemberInfo, opts ...rpc.CallOpt) (o0 SyncgroupSpec, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "JoinSyncgroup", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
	return
}

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

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

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

func (c implSyncgroupManagerClientStub) GetSyncgroupSpec(ctx *context.T, i0 string, opts ...rpc.CallOpt) (o0 SyncgroupSpec, o1 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetSyncgroupSpec", []interface{}{i0}, []interface{}{&o0, &o1}, opts...)
	return
}

func (c implSyncgroupManagerClientStub) SetSyncgroupSpec(ctx *context.T, i0 string, i1 SyncgroupSpec, i2 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "SetSyncgroupSpec", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

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

// SyncgroupManagerServerMethods is the interface a server writer
// implements for SyncgroupManager.
//
// SyncgroupManager is the interface for syncgroup operations.
// TODO(hpucha): Add blessings to create/join and add a refresh method.
type SyncgroupManagerServerMethods interface {
	// GetSyncgroupNames returns the global names of all syncgroups attached to
	// this database.
	GetSyncgroupNames(*context.T, rpc.ServerCall) ([]string, error)
	// CreateSyncgroup creates a new syncgroup with the given spec.
	//
	// Requires: Client must have at least Read access on the Database; 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, sgName string, spec SyncgroupSpec, myInfo SyncgroupMemberInfo) error
	// JoinSyncgroup joins the syncgroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	JoinSyncgroup(_ *context.T, _ rpc.ServerCall, sgName string, 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, sgName string) error
	// DestroySyncgroup destroys the syncgroup. Previously synced data will
	// continue to be available to all members.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	DestroySyncgroup(_ *context.T, _ rpc.ServerCall, sgName string) error
	// EjectFromSyncgroup ejects a member from the syncgroup. The ejected member
	// will not be able to sync further, but will retain any data it has already
	// synced.
	//
	// Requires: Client must have at least Read access on the Database, and must
	// have Admin access on the syncgroup ACL.
	EjectFromSyncgroup(_ *context.T, _ rpc.ServerCall, sgName string, member string) error
	// GetSyncgroupSpec gets the syncgroup spec. version allows for atomic
	// read-modify-write of the spec - see comment for SetSyncgroupSpec.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	GetSyncgroupSpec(_ *context.T, _ rpc.ServerCall, sgName string) (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, sgName string, spec SyncgroupSpec, version string) error
	// GetSyncgroupMembers gets the info objects for members of the syncgroup.
	//
	// Requires: Client must have at least Read access on the Database and on the
	// syncgroup ACL.
	GetSyncgroupMembers(_ *context.T, _ rpc.ServerCall, sgName string) (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) GetSyncgroupNames(ctx *context.T, call rpc.ServerCall) ([]string, error) {
	return s.impl.GetSyncgroupNames(ctx, call)
}

func (s implSyncgroupManagerServerStub) CreateSyncgroup(ctx *context.T, call rpc.ServerCall, i0 string, i1 SyncgroupSpec, i2 SyncgroupMemberInfo) error {
	return s.impl.CreateSyncgroup(ctx, call, i0, i1, i2)
}

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

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

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

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

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

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

func (s implSyncgroupManagerServerStub) GetSyncgroupMembers(ctx *context.T, call rpc.ServerCall, i0 string) (map[string]SyncgroupMemberInfo, error) {
	return s.impl.GetSyncgroupMembers(ctx, call, i0)
}

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

func (s implSyncgroupManagerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{SyncgroupManagerDesc}
}

// SyncgroupManagerDesc describes the SyncgroupManager interface.
var SyncgroupManagerDesc rpc.InterfaceDesc = descSyncgroupManager

// descSyncgroupManager hides the desc to keep godoc clean.
var descSyncgroupManager = rpc.InterfaceDesc{
	Name:    "SyncgroupManager",
	PkgPath: "v.io/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: "GetSyncgroupNames",
			Doc:  "// GetSyncgroupNames returns the global names of all syncgroups attached to\n// this database.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "CreateSyncgroup",
			Doc:  "// CreateSyncgroup creates a new syncgroup with the given spec.\n//\n// Requires: Client must have at least Read access on the Database; 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{
				{"sgName", ``}, // string
				{"spec", ``},   // SyncgroupSpec
				{"myInfo", ``}, // SyncgroupMemberInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "JoinSyncgroup",
			Doc:  "// JoinSyncgroup joins the syncgroup.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
				{"myInfo", ``}, // SyncgroupMemberInfo
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``}, // SyncgroupSpec
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "LeaveSyncgroup",
			Doc:  "// LeaveSyncgroup leaves the syncgroup. Previously synced data will continue\n// to be available.\n//\n// Requires: Client must have at least Read access on the Database.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DestroySyncgroup",
			Doc:  "// DestroySyncgroup destroys the syncgroup. Previously synced data will\n// continue to be available to all members.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "EjectFromSyncgroup",
			Doc:  "// EjectFromSyncgroup ejects a member from the syncgroup. The ejected member\n// will not be able to sync further, but will retain any data it has already\n// synced.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
				{"member", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetSyncgroupSpec",
			Doc:  "// GetSyncgroupSpec gets the syncgroup spec. version allows for atomic\n// read-modify-write of the spec - see comment for SetSyncgroupSpec.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"spec", ``},    // SyncgroupSpec
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "SetSyncgroupSpec",
			Doc:  "// SetSyncgroupSpec sets the syncgroup spec. version may be either empty or\n// the value from a previous Get. If not empty, Set will only succeed if the\n// current version matches the specified one.\n//\n// Requires: Client must have at least Read access on the Database, and must\n// have Admin access on the syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``},  // string
				{"spec", ``},    // SyncgroupSpec
				{"version", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetSyncgroupMembers",
			Doc:  "// GetSyncgroupMembers gets the info objects for members of the syncgroup.\n//\n// Requires: Client must have at least Read access on the Database and on the\n// syncgroup ACL.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"members", ``}, // map[string]SyncgroupMemberInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// BlobManagerClientMethods is the client interface
// containing BlobManager methods.
//
// BlobManager is the interface for blob operations.
//
// Description of API for resumable blob creation (append-only):
// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
//   current blob size via GetBlobSize and appending to the blob via PutBlob.
// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
//   may no longer be used.
// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
//   after commit.
type BlobManagerClientMethods interface {
	// CreateBlob returns a BlobRef for a newly created blob.
	CreateBlob(*context.T, ...rpc.CallOpt) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) (BlobManagerPutBlobClientCall, error)
	// CommitBlob marks the blob as immutable.
	CommitBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(_ *context.T, br BlobRef, _ ...rpc.CallOpt) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	GetBlob(_ *context.T, br BlobRef, offset int64, _ ...rpc.CallOpt) (BlobManagerGetBlobClientCall, error)
	// FetchBlob initiates fetching a blob if not locally found. priority
	// controls the network priority of the blob. Higher priority blobs are
	// fetched before the lower priority ones. However, an ongoing blob
	// transfer is not interrupted. Status updates are streamed back to the
	// client as fetch is in progress.
	FetchBlob(_ *context.T, br BlobRef, priority uint64, _ ...rpc.CallOpt) (BlobManagerFetchBlobClientCall, error)
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(_ *context.T, br BlobRef, _ ...rpc.CallOpt) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	KeepBlob(_ *context.T, br BlobRef, rank uint64, _ ...rpc.CallOpt) error
}

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

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

type implBlobManagerClientStub struct {
	name string
}

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

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

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

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

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

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

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

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

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

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

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

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

type implBlobManagerPutBlobClientCall struct {
	rpc.ClientCall
}

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

type implBlobManagerPutBlobClientCallSend struct {
	c *implBlobManagerPutBlobClientCall
}

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

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

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

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

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

type implBlobManagerGetBlobClientCallRecv struct {
	c *implBlobManagerGetBlobClientCall
}

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

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

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

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

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

type implBlobManagerFetchBlobClientCallRecv struct {
	c *implBlobManagerFetchBlobClientCall
}

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

// BlobManagerServerMethods is the interface a server writer
// implements for BlobManager.
//
// BlobManager is the interface for blob operations.
//
// Description of API for resumable blob creation (append-only):
// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
//   current blob size via GetBlobSize and appending to the blob via PutBlob.
// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
//   may no longer be used.
// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
//   after commit.
type BlobManagerServerMethods interface {
	// CreateBlob returns a BlobRef for a newly created blob.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(_ *context.T, _ BlobManagerPutBlobServerCall, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	CommitBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(_ *context.T, _ rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	GetBlob(_ *context.T, _ BlobManagerGetBlobServerCall, br BlobRef, offset int64) error
	// FetchBlob initiates fetching a blob if not locally found. priority
	// controls the network priority of the blob. Higher priority blobs are
	// fetched before the lower priority ones. However, an ongoing blob
	// transfer is not interrupted. Status updates are streamed back to the
	// client as fetch is in progress.
	FetchBlob(_ *context.T, _ BlobManagerFetchBlobServerCall, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	KeepBlob(_ *context.T, _ rpc.ServerCall, br BlobRef, rank uint64) error
}

// BlobManagerServerStubMethods is the server interface containing
// BlobManager methods, as expected by rpc.Server.
// The only difference between this interface and BlobManagerServerMethods
// is the streaming methods.
type BlobManagerServerStubMethods interface {
	// CreateBlob returns a BlobRef for a newly created blob.
	CreateBlob(*context.T, rpc.ServerCall) (br BlobRef, _ error)
	// PutBlob appends the byte stream to the blob.
	PutBlob(_ *context.T, _ *BlobManagerPutBlobServerCallStub, br BlobRef) error
	// CommitBlob marks the blob as immutable.
	CommitBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlobSize returns the count of bytes written as part of the blob
	// (committed or uncommitted).
	GetBlobSize(_ *context.T, _ rpc.ServerCall, br BlobRef) (int64, error)
	// DeleteBlob locally deletes the blob (committed or uncommitted).
	DeleteBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// GetBlob returns the byte stream from a committed blob starting at offset.
	GetBlob(_ *context.T, _ *BlobManagerGetBlobServerCallStub, br BlobRef, offset int64) error
	// FetchBlob initiates fetching a blob if not locally found. priority
	// controls the network priority of the blob. Higher priority blobs are
	// fetched before the lower priority ones. However, an ongoing blob
	// transfer is not interrupted. Status updates are streamed back to the
	// client as fetch is in progress.
	FetchBlob(_ *context.T, _ *BlobManagerFetchBlobServerCallStub, br BlobRef, priority uint64) error
	// PinBlob locally pins the blob so that it is not evicted.
	PinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// UnpinBlob locally unpins the blob so that it can be evicted if needed.
	UnpinBlob(_ *context.T, _ rpc.ServerCall, br BlobRef) error
	// KeepBlob locally caches the blob with the specified rank. Lower
	// ranked blobs are more eagerly evicted.
	KeepBlob(_ *context.T, _ rpc.ServerCall, br BlobRef, rank uint64) error
}

// BlobManagerServerStub adds universal methods to BlobManagerServerStubMethods.
type BlobManagerServerStub interface {
	BlobManagerServerStubMethods
	// Describe the BlobManager interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

type implBlobManagerServerStub struct {
	impl BlobManagerServerMethods
	gs   *rpc.GlobState
}

func (s implBlobManagerServerStub) CreateBlob(ctx *context.T, call rpc.ServerCall) (BlobRef, error) {
	return s.impl.CreateBlob(ctx, call)
}

func (s implBlobManagerServerStub) PutBlob(ctx *context.T, call *BlobManagerPutBlobServerCallStub, i0 BlobRef) error {
	return s.impl.PutBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) CommitBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.CommitBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) GetBlobSize(ctx *context.T, call rpc.ServerCall, i0 BlobRef) (int64, error) {
	return s.impl.GetBlobSize(ctx, call, i0)
}

func (s implBlobManagerServerStub) DeleteBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.DeleteBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) GetBlob(ctx *context.T, call *BlobManagerGetBlobServerCallStub, i0 BlobRef, i1 int64) error {
	return s.impl.GetBlob(ctx, call, i0, i1)
}

func (s implBlobManagerServerStub) FetchBlob(ctx *context.T, call *BlobManagerFetchBlobServerCallStub, i0 BlobRef, i1 uint64) error {
	return s.impl.FetchBlob(ctx, call, i0, i1)
}

func (s implBlobManagerServerStub) PinBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.PinBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) UnpinBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef) error {
	return s.impl.UnpinBlob(ctx, call, i0)
}

func (s implBlobManagerServerStub) KeepBlob(ctx *context.T, call rpc.ServerCall, i0 BlobRef, i1 uint64) error {
	return s.impl.KeepBlob(ctx, call, i0, i1)
}

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

func (s implBlobManagerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{BlobManagerDesc}
}

// BlobManagerDesc describes the BlobManager interface.
var BlobManagerDesc rpc.InterfaceDesc = descBlobManager

// descBlobManager hides the desc to keep godoc clean.
var descBlobManager = rpc.InterfaceDesc{
	Name:    "BlobManager",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// BlobManager is the interface for blob operations.\n//\n// Description of API for resumable blob creation (append-only):\n// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,\n//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the\n//   current blob size via GetBlobSize and appending to the blob via PutBlob.\n// - After commit, a blob is immutable, at which point PutBlob and CommitBlob\n//   may no longer be used.\n// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used\n//   after commit.",
	Methods: []rpc.MethodDesc{
		{
			Name: "CreateBlob",
			Doc:  "// CreateBlob returns a BlobRef for a newly created blob.",
			OutArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "PutBlob",
			Doc:  "// PutBlob appends the byte stream to the blob.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "CommitBlob",
			Doc:  "// CommitBlob marks the blob as immutable.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "GetBlobSize",
			Doc:  "// GetBlobSize returns the count of bytes written as part of the blob\n// (committed or uncommitted).",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DeleteBlob",
			Doc:  "// DeleteBlob locally deletes the blob (committed or uncommitted).",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "GetBlob",
			Doc:  "// GetBlob returns the byte stream from a committed blob starting at offset.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},     // BlobRef
				{"offset", ``}, // int64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "FetchBlob",
			Doc:  "// FetchBlob initiates fetching a blob if not locally found. priority\n// controls the network priority of the blob. Higher priority blobs are\n// fetched before the lower priority ones. However, an ongoing blob\n// transfer is not interrupted. Status updates are streamed back to the\n// client as fetch is in progress.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},       // BlobRef
				{"priority", ``}, // uint64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "PinBlob",
			Doc:  "// PinBlob locally pins the blob so that it is not evicted.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "UnpinBlob",
			Doc:  "// UnpinBlob locally unpins the blob so that it can be evicted if needed.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // BlobRef
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "KeepBlob",
			Doc:  "// KeepBlob locally caches the blob with the specified rank. Lower\n// ranked blobs are more eagerly evicted.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},   // BlobRef
				{"rank", ``}, // uint64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

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

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

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

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

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

type implBlobManagerPutBlobServerCallRecv struct {
	s *BlobManagerPutBlobServerCallStub
}

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

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

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

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

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

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

type implBlobManagerGetBlobServerCallSend struct {
	s *BlobManagerGetBlobServerCallStub
}

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

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

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

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

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

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

type implBlobManagerFetchBlobServerCallSend struct {
	s *BlobManagerFetchBlobServerCallStub
}

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

// SchemaManagerClientMethods is the client interface
// containing SchemaManager methods.
//
// SchemaManager implements the API for managing schema metadata attached
// to a Database.
type SchemaManagerClientMethods interface {
	// GetSchemaMetadata retrieves schema metadata for this database.
	//
	// Requires: Client must have at least Read access on the Database.
	GetSchemaMetadata(*context.T, ...rpc.CallOpt) (SchemaMetadata, error)
	// SetSchemaMetadata stores schema metadata for this database.
	//
	// Requires: Client must have at least Write access on the Database.
	SetSchemaMetadata(_ *context.T, metadata SchemaMetadata, _ ...rpc.CallOpt) error
}

// SchemaManagerClientStub adds universal methods to SchemaManagerClientMethods.
type SchemaManagerClientStub interface {
	SchemaManagerClientMethods
	rpc.UniversalServiceMethods
}

// SchemaManagerClient returns a client stub for SchemaManager.
func SchemaManagerClient(name string) SchemaManagerClientStub {
	return implSchemaManagerClientStub{name}
}

type implSchemaManagerClientStub struct {
	name string
}

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

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

// SchemaManagerServerMethods is the interface a server writer
// implements for SchemaManager.
//
// SchemaManager implements the API for managing schema metadata attached
// to a Database.
type SchemaManagerServerMethods interface {
	// GetSchemaMetadata retrieves schema metadata for this database.
	//
	// Requires: Client must have at least Read access on the Database.
	GetSchemaMetadata(*context.T, rpc.ServerCall) (SchemaMetadata, error)
	// SetSchemaMetadata stores schema metadata for this database.
	//
	// Requires: Client must have at least Write access on the Database.
	SetSchemaMetadata(_ *context.T, _ rpc.ServerCall, metadata SchemaMetadata) error
}

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

// SchemaManagerServerStub adds universal methods to SchemaManagerServerStubMethods.
type SchemaManagerServerStub interface {
	SchemaManagerServerStubMethods
	// Describe the SchemaManager interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

type implSchemaManagerServerStub struct {
	impl SchemaManagerServerMethods
	gs   *rpc.GlobState
}

func (s implSchemaManagerServerStub) GetSchemaMetadata(ctx *context.T, call rpc.ServerCall) (SchemaMetadata, error) {
	return s.impl.GetSchemaMetadata(ctx, call)
}

func (s implSchemaManagerServerStub) SetSchemaMetadata(ctx *context.T, call rpc.ServerCall, i0 SchemaMetadata) error {
	return s.impl.SetSchemaMetadata(ctx, call, i0)
}

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

func (s implSchemaManagerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{SchemaManagerDesc}
}

// SchemaManagerDesc describes the SchemaManager interface.
var SchemaManagerDesc rpc.InterfaceDesc = descSchemaManager

// descSchemaManager hides the desc to keep godoc clean.
var descSchemaManager = rpc.InterfaceDesc{
	Name:    "SchemaManager",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// SchemaManager implements the API for managing schema metadata attached\n// to a Database.",
	Methods: []rpc.MethodDesc{
		{
			Name: "GetSchemaMetadata",
			Doc:  "// GetSchemaMetadata retrieves schema metadata for this database.\n//\n// Requires: Client must have at least Read access on the Database.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // SchemaMetadata
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "SetSchemaMetadata",
			Doc:  "// SetSchemaMetadata stores schema metadata for this database.\n//\n// Requires: Client must have at least Write access on the Database.",
			InArgs: []rpc.ArgDesc{
				{"metadata", ``}, // SchemaMetadata
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

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

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

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

type implConflictManagerClientStub struct {
	name string
}

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

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

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

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

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

type implConflictManagerStartConflictResolverClientCallRecv struct {
	c *implConflictManagerStartConflictResolverClientCall
}

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

type implConflictManagerStartConflictResolverClientCallSend struct {
	c *implConflictManagerStartConflictResolverClientCall
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

type implConflictManagerStartConflictResolverServerCallRecv struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

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

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

type implConflictManagerStartConflictResolverServerCallSend struct {
	s *ConflictManagerStartConflictResolverServerCallStub
}

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

// DatabaseClientMethods is the client interface
// containing Database methods.
//
// Database represents a set of Collections. Batches, queries, syncgroups, and
// watch all operate at the Database level.
// Database.Glob operates over Collection ids.
type DatabaseClientMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectClientMethods
	// DatabaseWatcher allows a client to watch for updates to the database. For
	// each watch request, the client will receive a reliable stream of watch events
	// without re-ordering. See watch.GlobWatcher for a detailed explanation of the
	// behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// "<collectionId>/<rowPrefix>*". Consider changing that.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field in
	// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
	// type. If the client has no access to a row specified in a change, that change
	// is excluded from the result stream.
	//
	// Note: A single Watch Change batch may contain changes from more than one
	// batch as originally committed on a remote Syncbase or obtained from conflict
	// resolution. However, changes from a single original batch will always appear
	// in the same Change batch.
	DatabaseWatcherClientMethods
	// SyncgroupManager is the interface for syncgroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncgroupManagerClientMethods
	// BlobManager is the interface for blob operations.
	//
	// Description of API for resumable blob creation (append-only):
	// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
	//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
	//   current blob size via GetBlobSize and appending to the blob via PutBlob.
	// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
	//   may no longer be used.
	// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
	//   after commit.
	BlobManagerClientMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerClientMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerClientMethods
	// Create creates this Database.
	// TODO(sadovsky): Specify what happens if perms is nil.
	// Create requires the caller to have Write permission at the Service.
	Create(_ *context.T, metadata *SchemaMetadata, perms access.Permissions, _ ...rpc.CallOpt) error
	// Destroy destroys this Database, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(*context.T, ...rpc.CallOpt) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	Exists(*context.T, ...rpc.CallOpt) (bool, error)
	// ListCollections returns an unsorted list of all Collection ids that the
	// caller is allowed to see.
	// This method exists on Database but not on Service because for the latter
	// we can simply use glob, while for the former glob lists only Collections
	// visible in a new snapshot of the Database, ignoring user batches.
	// (Note that the same issue is present in glob on Collection, where Scan can
	// be used instead if batch awareness is required.)
	// Note, the glob client library checks Resolve access on every component
	// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen
	// for other RPCs.
	// TODO(ivanpi): Resolve should be checked on all RPCs.
	// TODO(sadovsky): Maybe switch to streaming RPC.
	ListCollections(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) ([]Id, error)
	// Exec executes a syncQL query with positional parameters and returns all
	// results as specified by the query's select/delete statement.
	// Concurrency semantics are documented in model.go.
	Exec(_ *context.T, bh BatchHandle, query string, params []*vom.RawBytes, _ ...rpc.CallOpt) (DatabaseExecClientCall, error)
	// BeginBatch creates a new batch. It returns a batch handle to pass in when
	// calling batch-aware RPCs.
	// Concurrency semantics are documented in model.go.
	// All batch-aware RPCs can also be called outside a batch (with an empty
	// handle), with the exception of Commit and Abort which only make sense on
	// a batch. Note that glob RPCs are not batch-aware.
	// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to
	// 'opts' once v.io/i/912 is resolved for Java.
	BeginBatch(_ *context.T, bo BatchOptions, _ ...rpc.CallOpt) (BatchHandle, error)
	// Commit persists the pending changes to the database.
	// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()
	// should be used instead.
	// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.
	Commit(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
	// Abort notifies the server that any pending changes can be discarded.
	// It is not strictly required, but it may allow the server to release locks
	// or other resources sooner than if it was not called.
	// If the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.
	Abort(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
	// PauseSync pauses sync for this database. Incoming sync, as well as outgoing
	// sync of subsequent writes, will be disabled until ResumeSync is called.
	// PauseSync is idempotent.
	PauseSync(*context.T, ...rpc.CallOpt) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	ResumeSync(*context.T, ...rpc.CallOpt) error
}

// DatabaseClientStub adds universal methods to DatabaseClientMethods.
type DatabaseClientStub interface {
	DatabaseClientMethods
	rpc.UniversalServiceMethods
}

// DatabaseClient returns a client stub for Database.
func DatabaseClient(name string) DatabaseClientStub {
	return implDatabaseClientStub{name, permissions.ObjectClient(name), DatabaseWatcherClient(name), SyncgroupManagerClient(name), BlobManagerClient(name), SchemaManagerClient(name), ConflictManagerClient(name)}
}

type implDatabaseClientStub struct {
	name string

	permissions.ObjectClientStub
	DatabaseWatcherClientStub
	SyncgroupManagerClientStub
	BlobManagerClientStub
	SchemaManagerClientStub
	ConflictManagerClientStub
}

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

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

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

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

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

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

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

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

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

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

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

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

type implDatabaseExecClientCall struct {
	rpc.ClientCall
	valRecv []*vom.RawBytes
	errRecv error
}

func (c *implDatabaseExecClientCall) RecvStream() interface {
	Advance() bool
	Value() []*vom.RawBytes
	Err() error
} {
	return implDatabaseExecClientCallRecv{c}
}

type implDatabaseExecClientCallRecv struct {
	c *implDatabaseExecClientCall
}

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

// DatabaseServerMethods is the interface a server writer
// implements for Database.
//
// Database represents a set of Collections. Batches, queries, syncgroups, and
// watch all operate at the Database level.
// Database.Glob operates over Collection ids.
type DatabaseServerMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerMethods
	// DatabaseWatcher allows a client to watch for updates to the database. For
	// each watch request, the client will receive a reliable stream of watch events
	// without re-ordering. See watch.GlobWatcher for a detailed explanation of the
	// behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// "<collectionId>/<rowPrefix>*". Consider changing that.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field in
	// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
	// type. If the client has no access to a row specified in a change, that change
	// is excluded from the result stream.
	//
	// Note: A single Watch Change batch may contain changes from more than one
	// batch as originally committed on a remote Syncbase or obtained from conflict
	// resolution. However, changes from a single original batch will always appear
	// in the same Change batch.
	DatabaseWatcherServerMethods
	// SyncgroupManager is the interface for syncgroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncgroupManagerServerMethods
	// BlobManager is the interface for blob operations.
	//
	// Description of API for resumable blob creation (append-only):
	// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
	//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
	//   current blob size via GetBlobSize and appending to the blob via PutBlob.
	// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
	//   may no longer be used.
	// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
	//   after commit.
	BlobManagerServerMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerServerMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerServerMethods
	// Create creates this Database.
	// TODO(sadovsky): Specify what happens if perms is nil.
	// Create requires the caller to have Write permission at the Service.
	Create(_ *context.T, _ rpc.ServerCall, metadata *SchemaMetadata, perms access.Permissions) error
	// Destroy destroys this Database, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(*context.T, rpc.ServerCall) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	Exists(*context.T, rpc.ServerCall) (bool, error)
	// ListCollections returns an unsorted list of all Collection ids that the
	// caller is allowed to see.
	// This method exists on Database but not on Service because for the latter
	// we can simply use glob, while for the former glob lists only Collections
	// visible in a new snapshot of the Database, ignoring user batches.
	// (Note that the same issue is present in glob on Collection, where Scan can
	// be used instead if batch awareness is required.)
	// Note, the glob client library checks Resolve access on every component
	// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen
	// for other RPCs.
	// TODO(ivanpi): Resolve should be checked on all RPCs.
	// TODO(sadovsky): Maybe switch to streaming RPC.
	ListCollections(_ *context.T, _ rpc.ServerCall, bh BatchHandle) ([]Id, error)
	// Exec executes a syncQL query with positional parameters and returns all
	// results as specified by the query's select/delete statement.
	// Concurrency semantics are documented in model.go.
	Exec(_ *context.T, _ DatabaseExecServerCall, bh BatchHandle, query string, params []*vom.RawBytes) error
	// BeginBatch creates a new batch. It returns a batch handle to pass in when
	// calling batch-aware RPCs.
	// Concurrency semantics are documented in model.go.
	// All batch-aware RPCs can also be called outside a batch (with an empty
	// handle), with the exception of Commit and Abort which only make sense on
	// a batch. Note that glob RPCs are not batch-aware.
	// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to
	// 'opts' once v.io/i/912 is resolved for Java.
	BeginBatch(_ *context.T, _ rpc.ServerCall, bo BatchOptions) (BatchHandle, error)
	// Commit persists the pending changes to the database.
	// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()
	// should be used instead.
	// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.
	Commit(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Abort notifies the server that any pending changes can be discarded.
	// It is not strictly required, but it may allow the server to release locks
	// or other resources sooner than if it was not called.
	// If the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.
	Abort(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// PauseSync pauses sync for this database. Incoming sync, as well as outgoing
	// sync of subsequent writes, will be disabled until ResumeSync is called.
	// PauseSync is idempotent.
	PauseSync(*context.T, rpc.ServerCall) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	ResumeSync(*context.T, rpc.ServerCall) error
}

// DatabaseServerStubMethods is the server interface containing
// Database methods, as expected by rpc.Server.
// The only difference between this interface and DatabaseServerMethods
// is the streaming methods.
type DatabaseServerStubMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerStubMethods
	// DatabaseWatcher allows a client to watch for updates to the database. For
	// each watch request, the client will receive a reliable stream of watch events
	// without re-ordering. See watch.GlobWatcher for a detailed explanation of the
	// behavior.
	// TODO(rogulenko): Currently the only supported watch patterns are
	// "<collectionId>/<rowPrefix>*". Consider changing that.
	//
	// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker
	// argument that points to a particular place in the database event log. If an
	// empty ResumeMarker is provided, the WatchStream will begin with a Change
	// batch containing the initial state. Otherwise, the WatchStream will contain
	// only changes since the provided ResumeMarker.
	//
	// The result stream consists of a never-ending sequence of Change messages
	// (until the call fails or is canceled). Each Change contains the Name field in
	// the form "<collectionId>/<rowKey>" and the Value field of the StoreChange
	// type. If the client has no access to a row specified in a change, that change
	// is excluded from the result stream.
	//
	// Note: A single Watch Change batch may contain changes from more than one
	// batch as originally committed on a remote Syncbase or obtained from conflict
	// resolution. However, changes from a single original batch will always appear
	// in the same Change batch.
	DatabaseWatcherServerStubMethods
	// SyncgroupManager is the interface for syncgroup operations.
	// TODO(hpucha): Add blessings to create/join and add a refresh method.
	SyncgroupManagerServerStubMethods
	// BlobManager is the interface for blob operations.
	//
	// Description of API for resumable blob creation (append-only):
	// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,
	//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the
	//   current blob size via GetBlobSize and appending to the blob via PutBlob.
	// - After commit, a blob is immutable, at which point PutBlob and CommitBlob
	//   may no longer be used.
	// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used
	//   after commit.
	BlobManagerServerStubMethods
	// SchemaManager implements the API for managing schema metadata attached
	// to a Database.
	SchemaManagerServerStubMethods
	// ConflictManager interface provides all the methods necessary to handle
	// conflict resolution for a given database.
	ConflictManagerServerStubMethods
	// Create creates this Database.
	// TODO(sadovsky): Specify what happens if perms is nil.
	// Create requires the caller to have Write permission at the Service.
	Create(_ *context.T, _ rpc.ServerCall, metadata *SchemaMetadata, perms access.Permissions) error
	// Destroy destroys this Database, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(*context.T, rpc.ServerCall) error
	// Exists returns true only if this Database exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	Exists(*context.T, rpc.ServerCall) (bool, error)
	// ListCollections returns an unsorted list of all Collection ids that the
	// caller is allowed to see.
	// This method exists on Database but not on Service because for the latter
	// we can simply use glob, while for the former glob lists only Collections
	// visible in a new snapshot of the Database, ignoring user batches.
	// (Note that the same issue is present in glob on Collection, where Scan can
	// be used instead if batch awareness is required.)
	// Note, the glob client library checks Resolve access on every component
	// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen
	// for other RPCs.
	// TODO(ivanpi): Resolve should be checked on all RPCs.
	// TODO(sadovsky): Maybe switch to streaming RPC.
	ListCollections(_ *context.T, _ rpc.ServerCall, bh BatchHandle) ([]Id, error)
	// Exec executes a syncQL query with positional parameters and returns all
	// results as specified by the query's select/delete statement.
	// Concurrency semantics are documented in model.go.
	Exec(_ *context.T, _ *DatabaseExecServerCallStub, bh BatchHandle, query string, params []*vom.RawBytes) error
	// BeginBatch creates a new batch. It returns a batch handle to pass in when
	// calling batch-aware RPCs.
	// Concurrency semantics are documented in model.go.
	// All batch-aware RPCs can also be called outside a batch (with an empty
	// handle), with the exception of Commit and Abort which only make sense on
	// a batch. Note that glob RPCs are not batch-aware.
	// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to
	// 'opts' once v.io/i/912 is resolved for Java.
	BeginBatch(_ *context.T, _ rpc.ServerCall, bo BatchOptions) (BatchHandle, error)
	// Commit persists the pending changes to the database.
	// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()
	// should be used instead.
	// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.
	Commit(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Abort notifies the server that any pending changes can be discarded.
	// It is not strictly required, but it may allow the server to release locks
	// or other resources sooner than if it was not called.
	// If the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.
	Abort(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// PauseSync pauses sync for this database. Incoming sync, as well as outgoing
	// sync of subsequent writes, will be disabled until ResumeSync is called.
	// PauseSync is idempotent.
	PauseSync(*context.T, rpc.ServerCall) error
	// ResumeSync resumes sync for this database. ResumeSync is idempotent.
	ResumeSync(*context.T, rpc.ServerCall) error
}

// DatabaseServerStub adds universal methods to DatabaseServerStubMethods.
type DatabaseServerStub interface {
	DatabaseServerStubMethods
	// Describe the Database interfaces.
	Describe__() []rpc.InterfaceDesc
}

// DatabaseServer returns a server stub for Database.
// It converts an implementation of DatabaseServerMethods into
// an object that may be used by rpc.Server.
func DatabaseServer(impl DatabaseServerMethods) DatabaseServerStub {
	stub := implDatabaseServerStub{
		impl:                       impl,
		ObjectServerStub:           permissions.ObjectServer(impl),
		DatabaseWatcherServerStub:  DatabaseWatcherServer(impl),
		SyncgroupManagerServerStub: SyncgroupManagerServer(impl),
		BlobManagerServerStub:      BlobManagerServer(impl),
		SchemaManagerServerStub:    SchemaManagerServer(impl),
		ConflictManagerServerStub:  ConflictManagerServer(impl),
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

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

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

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

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

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

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

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

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

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

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

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

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

func (s implDatabaseServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{DatabaseDesc, permissions.ObjectDesc, DatabaseWatcherDesc, watch.GlobWatcherDesc, SyncgroupManagerDesc, BlobManagerDesc, SchemaManagerDesc, ConflictManagerDesc}
}

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

// descDatabase hides the desc to keep godoc clean.
var descDatabase = rpc.InterfaceDesc{
	Name:    "Database",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Database represents a set of Collections. Batches, queries, syncgroups, and\n// watch all operate at the Database level.\n// Database.Glob operates over Collection ids.",
	Embeds: []rpc.EmbedDesc{
		{"Object", "v.io/v23/services/permissions", "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"},
		{"DatabaseWatcher", "v.io/v23/services/syncbase", "// DatabaseWatcher allows a client to watch for updates to the database. For\n// each watch request, the client will receive a reliable stream of watch events\n// without re-ordering. See watch.GlobWatcher for a detailed explanation of the\n// behavior.\n// TODO(rogulenko): Currently the only supported watch patterns are\n// \"<collectionId>/<rowPrefix>*\". Consider changing that.\n//\n// Watching is done by starting a streaming RPC. The RPC takes a ResumeMarker\n// argument that points to a particular place in the database event log. If an\n// empty ResumeMarker is provided, the WatchStream will begin with a Change\n// batch containing the initial state. Otherwise, the WatchStream will contain\n// only changes since the provided ResumeMarker.\n//\n// The result stream consists of a never-ending sequence of Change messages\n// (until the call fails or is canceled). Each Change contains the Name field in\n// the form \"<collectionId>/<rowKey>\" and the Value field of the StoreChange\n// type. If the client has no access to a row specified in a change, that change\n// is excluded from the result stream.\n//\n// Note: A single Watch Change batch may contain changes from more than one\n// batch as originally committed on a remote Syncbase or obtained from conflict\n// resolution. However, changes from a single original batch will always appear\n// in the same Change batch."},
		{"SyncgroupManager", "v.io/v23/services/syncbase", "// SyncgroupManager is the interface for syncgroup operations.\n// TODO(hpucha): Add blessings to create/join and add a refresh method."},
		{"BlobManager", "v.io/v23/services/syncbase", "// BlobManager is the interface for blob operations.\n//\n// Description of API for resumable blob creation (append-only):\n// - Up until commit, a BlobRef may be used with PutBlob, GetBlobSize,\n//   DeleteBlob, and CommitBlob. Blob creation may be resumed by obtaining the\n//   current blob size via GetBlobSize and appending to the blob via PutBlob.\n// - After commit, a blob is immutable, at which point PutBlob and CommitBlob\n//   may no longer be used.\n// - All other methods (GetBlob, FetchBlob, PinBlob, etc.) may only be used\n//   after commit."},
		{"SchemaManager", "v.io/v23/services/syncbase", "// SchemaManager implements the API for managing schema metadata attached\n// to a Database."},
		{"ConflictManager", "v.io/v23/services/syncbase", "// ConflictManager interface provides all the methods necessary to handle\n// conflict resolution for a given database."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Database.\n// TODO(sadovsky): Specify what happens if perms is nil.\n// Create requires the caller to have Write permission at the Service.",
			InArgs: []rpc.ArgDesc{
				{"metadata", ``}, // *SchemaMetadata
				{"perms", ``},    // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Destroy",
			Doc:  "// Destroy destroys this Database, permanently removing all of its data.\n// TODO(sadovsky): Specify what happens to syncgroups.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Database exists. Insufficient permissions\n// cause Exists to return false instead of an error.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Resolve"))},
		},
		{
			Name: "ListCollections",
			Doc:  "// ListCollections returns an unsorted list of all Collection ids that the\n// caller is allowed to see.\n// This method exists on Database but not on Service because for the latter\n// we can simply use glob, while for the former glob lists only Collections\n// visible in a new snapshot of the Database, ignoring user batches.\n// (Note that the same issue is present in glob on Collection, where Scan can\n// be used instead if batch awareness is required.)\n// Note, the glob client library checks Resolve access on every component\n// along the path (by doing a Dispatcher.Lookup), whereas this doesn't happen\n// for other RPCs.\n// TODO(ivanpi): Resolve should be checked on all RPCs.\n// TODO(sadovsky): Maybe switch to streaming RPC.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []Id
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Exec",
			Doc:  "// Exec executes a syncQL query with positional parameters and returns all\n// results as specified by the query's select/delete statement.\n// Concurrency semantics are documented in model.go.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},     // BatchHandle
				{"query", ``},  // string
				{"params", ``}, // []*vom.RawBytes
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "BeginBatch",
			Doc:  "// BeginBatch creates a new batch. It returns a batch handle to pass in when\n// calling batch-aware RPCs.\n// Concurrency semantics are documented in model.go.\n// All batch-aware RPCs can also be called outside a batch (with an empty\n// handle), with the exception of Commit and Abort which only make sense on\n// a batch. Note that glob RPCs are not batch-aware.\n// TODO(sadovsky): Maybe make BatchOptions optional. Also, rename 'bo' to\n// 'opts' once v.io/i/912 is resolved for Java.",
			InArgs: []rpc.ArgDesc{
				{"bo", ``}, // BatchOptions
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Commit",
			Doc:  "// Commit persists the pending changes to the database.\n// If the batch is readonly, Commit() will fail with ErrReadOnlyBatch; Abort()\n// should be used instead.\n// If the BatchHandle is empty, Commit() will fail with ErrNotBoundToBatch.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Abort",
			Doc:  "// Abort notifies the server that any pending changes can be discarded.\n// It is not strictly required, but it may allow the server to release locks\n// or other resources sooner than if it was not called.\n// If the BatchHandle is empty, Abort() will fail with ErrNotBoundToBatch.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "PauseSync",
			Doc:  "// PauseSync pauses sync for this database. Incoming sync, as well as outgoing\n// sync of subsequent writes, will be disabled until ResumeSync is called.\n// PauseSync is idempotent.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "ResumeSync",
			Doc:  "// ResumeSync resumes sync for this database. ResumeSync is idempotent.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

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

// DatabaseExecServerCall represents the context passed to Database.Exec.
type DatabaseExecServerCall interface {
	rpc.ServerCall
	DatabaseExecServerStream
}

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

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

// SendStream returns the send side of the Database.Exec server stream.
func (s *DatabaseExecServerCallStub) SendStream() interface {
	Send(item []*vom.RawBytes) error
} {
	return implDatabaseExecServerCallSend{s}
}

type implDatabaseExecServerCallSend struct {
	s *DatabaseExecServerCallStub
}

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

// CollectionClientMethods is the client interface
// containing Collection methods.
//
// Collection represents a set of Rows.
// Collection.Glob operates over keys of Rows in the Collection.
type CollectionClientMethods interface {
	// Create creates this Collection.
	// TODO(sadovsky): Specify what happens if perms is nil.
	Create(_ *context.T, bh BatchHandle, perms access.Permissions, _ ...rpc.CallOpt) error
	// Destroy destroys this Collection, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
	// Exists returns true only if this Collection exists. Insufficient
	// permissions cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	GetPermissions(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the Collection.
	SetPermissions(_ *context.T, bh BatchHandle, perms access.Permissions, _ ...rpc.CallOpt) error
	// DeleteRange deletes all rows in the given half-open range [start, limit).
	// If limit is "", all rows with keys >= start are included.
	DeleteRange(_ *context.T, bh BatchHandle, start []byte, limit []byte, _ ...rpc.CallOpt) error
	// Scan returns all rows in the given half-open range [start, limit). If limit
	// is "", all rows with keys >= start are included.
	// Concurrency semantics are documented in model.go.
	Scan(_ *context.T, bh BatchHandle, start []byte, limit []byte, _ ...rpc.CallOpt) (CollectionScanClientCall, error)
}

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

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

type implCollectionClientStub struct {
	name string
}

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

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

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

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

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

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

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

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

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

type implCollectionScanClientCall struct {
	rpc.ClientCall
	valRecv KeyValue
	errRecv error
}

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

type implCollectionScanClientCallRecv struct {
	c *implCollectionScanClientCall
}

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

// CollectionServerMethods is the interface a server writer
// implements for Collection.
//
// Collection represents a set of Rows.
// Collection.Glob operates over keys of Rows in the Collection.
type CollectionServerMethods interface {
	// Create creates this Collection.
	// TODO(sadovsky): Specify what happens if perms is nil.
	Create(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// Destroy destroys this Collection, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Exists returns true only if this Collection exists. Insufficient
	// permissions cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	GetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the Collection.
	SetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// DeleteRange deletes all rows in the given half-open range [start, limit).
	// If limit is "", all rows with keys >= start are included.
	DeleteRange(_ *context.T, _ rpc.ServerCall, bh BatchHandle, start []byte, limit []byte) error
	// Scan returns all rows in the given half-open range [start, limit). If limit
	// is "", all rows with keys >= start are included.
	// Concurrency semantics are documented in model.go.
	Scan(_ *context.T, _ CollectionScanServerCall, bh BatchHandle, start []byte, limit []byte) error
}

// CollectionServerStubMethods is the server interface containing
// Collection methods, as expected by rpc.Server.
// The only difference between this interface and CollectionServerMethods
// is the streaming methods.
type CollectionServerStubMethods interface {
	// Create creates this Collection.
	// TODO(sadovsky): Specify what happens if perms is nil.
	Create(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// Destroy destroys this Collection, permanently removing all of its data.
	// TODO(sadovsky): Specify what happens to syncgroups.
	Destroy(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
	// Exists returns true only if this Collection exists. Insufficient
	// permissions cause Exists to return false instead of an error.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// GetPermissions returns the current Permissions for the Collection.
	GetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (access.Permissions, error)
	// SetPermissions replaces the current Permissions for the Collection.
	SetPermissions(_ *context.T, _ rpc.ServerCall, bh BatchHandle, perms access.Permissions) error
	// DeleteRange deletes all rows in the given half-open range [start, limit).
	// If limit is "", all rows with keys >= start are included.
	DeleteRange(_ *context.T, _ rpc.ServerCall, bh BatchHandle, start []byte, limit []byte) error
	// Scan returns all rows in the given half-open range [start, limit). If limit
	// is "", all rows with keys >= start are included.
	// Concurrency semantics are documented in model.go.
	Scan(_ *context.T, _ *CollectionScanServerCallStub, bh BatchHandle, start []byte, limit []byte) error
}

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

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

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

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

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

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

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

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

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

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

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

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

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

// descCollection hides the desc to keep godoc clean.
var descCollection = rpc.InterfaceDesc{
	Name:    "Collection",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Collection represents a set of Rows.\n// Collection.Glob operates over keys of Rows in the Collection.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create creates this Collection.\n// TODO(sadovsky): Specify what happens if perms is nil.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"perms", ``}, // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Destroy",
			Doc:  "// Destroy destroys this Collection, permanently removing all of its data.\n// TODO(sadovsky): Specify what happens to syncgroups.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Collection exists. Insufficient\n// permissions cause Exists to return false instead of an error.\n// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy\n// do not exist.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Resolve"))},
		},
		{
			Name: "GetPermissions",
			Doc:  "// GetPermissions returns the current Permissions for the Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "SetPermissions",
			Doc:  "// SetPermissions replaces the current Permissions for the Collection.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"perms", ``}, // access.Permissions
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Admin"))},
		},
		{
			Name: "DeleteRange",
			Doc:  "// DeleteRange deletes all rows in the given half-open range [start, limit).\n// If limit is \"\", all rows with keys >= start are included.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"start", ``}, // []byte
				{"limit", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Scan",
			Doc:  "// Scan returns all rows in the given half-open range [start, limit). If limit\n// is \"\", all rows with keys >= start are included.\n// Concurrency semantics are documented in model.go.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"start", ``}, // []byte
				{"limit", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

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

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

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

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

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

type implCollectionScanServerCallSend struct {
	s *CollectionScanServerCallStub
}

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

// RowClientMethods is the client interface
// containing Row methods.
//
// Row represents a single row in a Collection.
// All access checks are performed against the Collection ACL.
type RowClientMethods interface {
	// Exists returns true only if this Row exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// Note, Exists on Row requires read permissions, unlike higher levels of
	// hierarchy which require resolve, because Row existence usually carries
	// more information.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (bool, error)
	// Get returns the value for this Row.
	Get(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) (*vom.RawBytes, error)
	// Put writes the given value for this Row.
	Put(_ *context.T, bh BatchHandle, value *vom.RawBytes, _ ...rpc.CallOpt) error
	// Delete deletes this Row.
	Delete(_ *context.T, bh BatchHandle, _ ...rpc.CallOpt) error
}

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

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

type implRowClientStub struct {
	name string
}

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

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

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

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

// RowServerMethods is the interface a server writer
// implements for Row.
//
// Row represents a single row in a Collection.
// All access checks are performed against the Collection ACL.
type RowServerMethods interface {
	// Exists returns true only if this Row exists. Insufficient permissions
	// cause Exists to return false instead of an error.
	// Note, Exists on Row requires read permissions, unlike higher levels of
	// hierarchy which require resolve, because Row existence usually carries
	// more information.
	// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy
	// do not exist.
	Exists(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (bool, error)
	// Get returns the value for this Row.
	Get(_ *context.T, _ rpc.ServerCall, bh BatchHandle) (*vom.RawBytes, error)
	// Put writes the given value for this Row.
	Put(_ *context.T, _ rpc.ServerCall, bh BatchHandle, value *vom.RawBytes) error
	// Delete deletes this Row.
	Delete(_ *context.T, _ rpc.ServerCall, bh BatchHandle) error
}

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

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

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

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

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

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

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

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

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

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

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

// descRow hides the desc to keep godoc clean.
var descRow = rpc.InterfaceDesc{
	Name:    "Row",
	PkgPath: "v.io/v23/services/syncbase",
	Doc:     "// Row represents a single row in a Collection.\n// All access checks are performed against the Collection ACL.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Exists",
			Doc:  "// Exists returns true only if this Row exists. Insufficient permissions\n// cause Exists to return false instead of an error.\n// Note, Exists on Row requires read permissions, unlike higher levels of\n// hierarchy which require resolve, because Row existence usually carries\n// more information.\n// TODO(ivanpi): Exists may fail with an error if higher levels of hierarchy\n// do not exist.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Get",
			Doc:  "// Get returns the value for this Row.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // *vom.RawBytes
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Put",
			Doc:  "// Put writes the given value for this Row.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``},    // BatchHandle
				{"value", ``}, // *vom.RawBytes
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes this Row.",
			InArgs: []rpc.ArgDesc{
				{"bh", ``}, // BatchHandle
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

var __VDLInitCalled bool

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

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

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

	return struct{}{}
}
