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

import (
	"time"
	"v.io/v23/services/syncbase"
	"v.io/v23/vdl"
	vdltime "v.io/v23/vdlroot/time"
	"v.io/v23/vom"
)

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

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

// Value contains a specific version of data for the row under conflict along
// with the write timestamp and hints associated with the version.
// State defines whether the value is empty or not. It can be empty for
// reasons like Deleted or Unknown.
// WriteTs is the write timestamp for this value.
type Value struct {
	State   syncbase.ValueState
	Val     *vom.RawBytes
	WriteTs time.Time
	// TODO(jlodhia): Since field Selection cannot be package private in VDL,
	// review the ConflictResolution API to see if we should keep this field
	// or not.
	Selection syncbase.ValueSelection
}

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

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

func (x Value) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.State != syncbase.ValueStateExists {
		if err := enc.NextFieldValueString(0, __VDLType_enum_2, x.State.String()); err != nil {
			return err
		}
	}
	if x.Val != nil && !x.Val.VDLIsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.Val.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.WriteTs.IsZero() {
		if err := enc.NextField(2); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.WriteTs); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Selection != syncbase.ValueSelectionLocal {
		if err := enc.NextFieldValueString(3, __VDLType_enum_4, x.Selection.String()); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

// ConflictRow represents a row under conflict.
// Key is the key for the row.
// LocalValue is the value present in the local db.
// RemoteValue is the value received via sync.
// AncestorValue is the value for the key which is the lowest common
// ancestor of the two values represented by LocalValue and RemoteValue.
// AncestorValue's state is NoExists if the ConflictRow is a part of the read set.
// BatchIds is a list of ids of all the batches that this row belongs to.
type ConflictRow struct {
	Key           string
	LocalValue    Value
	RemoteValue   Value
	AncestorValue Value
	BatchIds      []uint64
}

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

func (x ConflictRow) VDLIsZero() bool {
	if x.Key != "" {
		return false
	}
	if !x.LocalValue.VDLIsZero() {
		return false
	}
	if !x.RemoteValue.VDLIsZero() {
		return false
	}
	if !x.AncestorValue.VDLIsZero() {
		return false
	}
	if len(x.BatchIds) != 0 {
		return false
	}
	return true
}

func (x ConflictRow) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_5); err != nil {
		return err
	}
	if x.Key != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Key); err != nil {
			return err
		}
	}
	if !x.LocalValue.VDLIsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.LocalValue.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.RemoteValue.VDLIsZero() {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := x.RemoteValue.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.AncestorValue.VDLIsZero() {
		if err := enc.NextField(3); err != nil {
			return err
		}
		if err := x.AncestorValue.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.BatchIds) != 0 {
		if err := enc.NextField(4); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.BatchIds); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

func (x *ConflictRow) VDLRead(dec vdl.Decoder) error {
	*x = ConflictRow{
		LocalValue: Value{
			Val: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
		},
		RemoteValue: Value{
			Val: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
		},
		AncestorValue: Value{
			Val: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
		},
	}
	if err := dec.StartValue(__VDLType_struct_5); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_5 {
			index = __VDLType_struct_5.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Key = value
			}
		case 1:
			if err := x.LocalValue.VDLRead(dec); err != nil {
				return err
			}
		case 2:
			if err := x.RemoteValue.VDLRead(dec); err != nil {
				return err
			}
		case 3:
			if err := x.AncestorValue.VDLRead(dec); err != nil {
				return err
			}
		case 4:
			if err := __VDLReadAnon_list_1(dec, &x.BatchIds); err != nil {
				return err
			}
		}
	}
}

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

// ConflictRowSet contains a set of rows under conflict. It provides two different
// ways to access the same set.
// ByKey is a map of ConflictRows keyed by the row key.
// ByBatch is a map of []ConflictRows keyed by batch id. This map lets the client
// access all ConflictRows within this set that contain a given hint.
type ConflictRowSet struct {
	ByKey   map[string]ConflictRow
	ByBatch map[uint64][]ConflictRow
}

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

func (x ConflictRowSet) VDLIsZero() bool {
	if len(x.ByKey) != 0 {
		return false
	}
	if len(x.ByBatch) != 0 {
		return false
	}
	return true
}

func (x ConflictRowSet) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_7); err != nil {
		return err
	}
	if len(x.ByKey) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_2(enc, x.ByKey); err != nil {
			return err
		}
	}
	if len(x.ByBatch) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_3(enc, x.ByBatch); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_2(enc vdl.Encoder, x map[string]ConflictRow) error {
	if err := enc.StartValue(__VDLType_map_8); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, key); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_3(enc vdl.Encoder, x map[uint64][]ConflictRow) error {
	if err := enc.StartValue(__VDLType_map_9); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntryValueUint(vdl.Uint64Type, key); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_4(enc, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

func __VDLReadAnon_map_2(dec vdl.Decoder, x *map[string]ConflictRow) error {
	if err := dec.StartValue(__VDLType_map_8); err != nil {
		return err
	}
	var tmpMap map[string]ConflictRow
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[string]ConflictRow, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem ConflictRow
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(map[string]ConflictRow)
			}
			tmpMap[key] = elem
		}
	}
}

func __VDLReadAnon_map_3(dec vdl.Decoder, x *map[uint64][]ConflictRow) error {
	if err := dec.StartValue(__VDLType_map_9); err != nil {
		return err
	}
	var tmpMap map[uint64][]ConflictRow
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[uint64][]ConflictRow, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueUint(64); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem []ConflictRow
			if err := __VDLReadAnon_list_4(dec, &elem); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(map[uint64][]ConflictRow)
			}
			tmpMap[key] = elem
		}
	}
}

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

// ConflictScanSet contains a set of scans under conflict.
// ByBatch is a map of array of ScanOps keyed by batch id.
type ConflictScanSet struct {
	ByBatch map[uint64][]syncbase.ScanOp
}

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

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

func (x ConflictScanSet) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_11); err != nil {
		return err
	}
	if len(x.ByBatch) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_5(enc, x.ByBatch); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_5(enc vdl.Encoder, x map[uint64][]syncbase.ScanOp) error {
	if err := enc.StartValue(__VDLType_map_12); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntryValueUint(vdl.Uint64Type, key); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_6(enc, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

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

func __VDLReadAnon_map_5(dec vdl.Decoder, x *map[uint64][]syncbase.ScanOp) error {
	if err := dec.StartValue(__VDLType_map_12); err != nil {
		return err
	}
	var tmpMap map[uint64][]syncbase.ScanOp
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[uint64][]syncbase.ScanOp, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueUint(64); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem []syncbase.ScanOp
			if err := __VDLReadAnon_list_6(dec, &elem); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(map[uint64][]syncbase.ScanOp)
			}
			tmpMap[key] = elem
		}
	}
}

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

// Conflict contains information to fully specify a conflict. Since syncbase
// supports batches there can be one or more rows within the batch that has a
// conflict. Each of these rows will be sent together as part of a single
// conflict. Each row contains an Id of the batch to which it belongs,
// enabling the client to group together rows that are part of a batch. Note
// that a single row can be part of more than one batch.
//
// WriteSet contains rows that were written.
// ReadSet contains rows that were read within a batch corresponding to a row
// within the write set.
// ScanSet contains scans performed within a batch corresponding to a row
// within the write set.
// Batches is a map of unique ids to BatchInfo objects. The id is unique only in
// the context of a given conflict and is otherwise meaningless.
type Conflict struct {
	ReadSet  *ConflictRowSet
	WriteSet *ConflictRowSet
	ScanSet  *ConflictScanSet
	Batches  map[uint64]syncbase.BatchInfo
}

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

func (x Conflict) VDLIsZero() bool {
	if x.ReadSet != nil {
		return false
	}
	if x.WriteSet != nil {
		return false
	}
	if x.ScanSet != nil {
		return false
	}
	if len(x.Batches) != 0 {
		return false
	}
	return true
}

func (x Conflict) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_15); err != nil {
		return err
	}
	if x.ReadSet != nil {
		if err := enc.NextField(0); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := x.ReadSet.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.WriteSet != nil {
		if err := enc.NextField(1); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := x.WriteSet.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.ScanSet != nil {
		if err := enc.NextField(2); err != nil {
			return err
		}
		enc.SetNextStartValueIsOptional()
		if err := x.ScanSet.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.Batches) != 0 {
		if err := enc.NextField(3); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_7(enc, x.Batches); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_7(enc vdl.Encoder, x map[uint64]syncbase.BatchInfo) error {
	if err := enc.StartValue(__VDLType_map_18); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntryValueUint(vdl.Uint64Type, key); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Conflict) VDLRead(dec vdl.Decoder) error {
	*x = Conflict{}
	if err := dec.StartValue(__VDLType_struct_15); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_15 {
			index = __VDLType_struct_15.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := dec.StartValue(__VDLType_optional_16); err != nil {
				return err
			}
			if dec.IsNil() {
				x.ReadSet = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.ReadSet = new(ConflictRowSet)
				dec.IgnoreNextStartValue()
				if err := x.ReadSet.VDLRead(dec); err != nil {
					return err
				}
			}
		case 1:
			if err := dec.StartValue(__VDLType_optional_16); err != nil {
				return err
			}
			if dec.IsNil() {
				x.WriteSet = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.WriteSet = new(ConflictRowSet)
				dec.IgnoreNextStartValue()
				if err := x.WriteSet.VDLRead(dec); err != nil {
					return err
				}
			}
		case 2:
			if err := dec.StartValue(__VDLType_optional_17); err != nil {
				return err
			}
			if dec.IsNil() {
				x.ScanSet = nil
				if err := dec.FinishValue(); err != nil {
					return err
				}
			} else {
				x.ScanSet = new(ConflictScanSet)
				dec.IgnoreNextStartValue()
				if err := x.ScanSet.VDLRead(dec); err != nil {
					return err
				}
			}
		case 3:
			if err := __VDLReadAnon_map_7(dec, &x.Batches); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_map_7(dec vdl.Decoder, x *map[uint64]syncbase.BatchInfo) error {
	if err := dec.StartValue(__VDLType_map_18); err != nil {
		return err
	}
	var tmpMap map[uint64]syncbase.BatchInfo
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[uint64]syncbase.BatchInfo, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueUint(64); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem syncbase.BatchInfo
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(map[uint64]syncbase.BatchInfo)
			}
			tmpMap[key] = elem
		}
	}
}

// ResolvedRow represents a result of resolution of a row under conflict.
// Key is the key for the row.
// Result is the result of the conflict resolution. Delete is represented
// by nil.
type ResolvedRow struct {
	Key    string
	Result *Value
}

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

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

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

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

// Resolution contains the application’s reply to a conflict. It must contain a
// resolved value for each conflict row within the WriteSet of the given
// conflict.
// ResultSet is a map of row key to ResolvedRow.
type Resolution struct {
	ResultSet map[string]ResolvedRow
}

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

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

func (x Resolution) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_22); err != nil {
		return err
	}
	if len(x.ResultSet) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_8(enc, x.ResultSet); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_8(enc vdl.Encoder, x map[string]ResolvedRow) error {
	if err := enc.StartValue(__VDLType_map_23); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, key); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

func __VDLReadAnon_map_8(dec vdl.Decoder, x *map[string]ResolvedRow) error {
	if err := dec.StartValue(__VDLType_map_23); err != nil {
		return err
	}
	var tmpMap map[string]ResolvedRow
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[string]ResolvedRow, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem ResolvedRow
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(map[string]ResolvedRow)
			}
			tmpMap[key] = elem
		}
	}
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1    *vdl.Type
	__VDLType_enum_2      *vdl.Type
	__VDLType_struct_3    *vdl.Type
	__VDLType_enum_4      *vdl.Type
	__VDLType_struct_5    *vdl.Type
	__VDLType_list_6      *vdl.Type
	__VDLType_struct_7    *vdl.Type
	__VDLType_map_8       *vdl.Type
	__VDLType_map_9       *vdl.Type
	__VDLType_list_10     *vdl.Type
	__VDLType_struct_11   *vdl.Type
	__VDLType_map_12      *vdl.Type
	__VDLType_list_13     *vdl.Type
	__VDLType_struct_14   *vdl.Type
	__VDLType_struct_15   *vdl.Type
	__VDLType_optional_16 *vdl.Type
	__VDLType_optional_17 *vdl.Type
	__VDLType_map_18      *vdl.Type
	__VDLType_struct_19   *vdl.Type
	__VDLType_struct_20   *vdl.Type
	__VDLType_optional_21 *vdl.Type
	__VDLType_struct_22   *vdl.Type
	__VDLType_map_23      *vdl.Type
)

var __VDLInitCalled bool

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

	// Register types.
	vdl.Register((*Value)(nil))
	vdl.Register((*ConflictRow)(nil))
	vdl.Register((*ConflictRowSet)(nil))
	vdl.Register((*ConflictScanSet)(nil))
	vdl.Register((*Conflict)(nil))
	vdl.Register((*ResolvedRow)(nil))
	vdl.Register((*Resolution)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*Value)(nil)).Elem()
	__VDLType_enum_2 = vdl.TypeOf((*syncbase.ValueState)(nil))
	__VDLType_struct_3 = vdl.TypeOf((*vdltime.Time)(nil)).Elem()
	__VDLType_enum_4 = vdl.TypeOf((*syncbase.ValueSelection)(nil))
	__VDLType_struct_5 = vdl.TypeOf((*ConflictRow)(nil)).Elem()
	__VDLType_list_6 = vdl.TypeOf((*[]uint64)(nil))
	__VDLType_struct_7 = vdl.TypeOf((*ConflictRowSet)(nil)).Elem()
	__VDLType_map_8 = vdl.TypeOf((*map[string]ConflictRow)(nil))
	__VDLType_map_9 = vdl.TypeOf((*map[uint64][]ConflictRow)(nil))
	__VDLType_list_10 = vdl.TypeOf((*[]ConflictRow)(nil))
	__VDLType_struct_11 = vdl.TypeOf((*ConflictScanSet)(nil)).Elem()
	__VDLType_map_12 = vdl.TypeOf((*map[uint64][]syncbase.ScanOp)(nil))
	__VDLType_list_13 = vdl.TypeOf((*[]syncbase.ScanOp)(nil))
	__VDLType_struct_14 = vdl.TypeOf((*syncbase.ScanOp)(nil)).Elem()
	__VDLType_struct_15 = vdl.TypeOf((*Conflict)(nil)).Elem()
	__VDLType_optional_16 = vdl.TypeOf((*ConflictRowSet)(nil))
	__VDLType_optional_17 = vdl.TypeOf((*ConflictScanSet)(nil))
	__VDLType_map_18 = vdl.TypeOf((*map[uint64]syncbase.BatchInfo)(nil))
	__VDLType_struct_19 = vdl.TypeOf((*syncbase.BatchInfo)(nil)).Elem()
	__VDLType_struct_20 = vdl.TypeOf((*ResolvedRow)(nil)).Elem()
	__VDLType_optional_21 = vdl.TypeOf((*Value)(nil))
	__VDLType_struct_22 = vdl.TypeOf((*Resolution)(nil)).Elem()
	__VDLType_map_23 = vdl.TypeOf((*map[string]ResolvedRow)(nil))

	return struct{}{}
}
