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

package vsync

import (
	"v.io/v23/vdl"
	"v.io/x/ref/services/syncbase/server/interfaces"
)

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

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

// SyncData represents the persistent state of the sync module.
type SyncData struct {
	Id uint64
}

func (SyncData) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/vsync.SyncData"`
}) {
}

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

func (x SyncData) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.Id != 0 {
		if err := enc.NextFieldValueUint("Id", vdl.Uint64Type, x.Id); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SyncData) VDLRead(dec vdl.Decoder) error {
	*x = SyncData{}
	if err := dec.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Id":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Id = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// DbSyncState represents the persistent sync state of a Database.
type DbSyncState struct {
	GenVecs   interfaces.Knowledge // knowledge capturing the locally-known generations of remote peers for data in Database.
	SgGenVecs interfaces.Knowledge // knowledge capturing the locally-known generations of remote peers for syncgroups in Database.
	IsPaused  bool                 // tracks whether sync is paused by client.
}

func (DbSyncState) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/vsync.DbSyncState"`
}) {
}

func (x DbSyncState) VDLIsZero() bool {
	if len(x.GenVecs) != 0 {
		return false
	}
	if len(x.SgGenVecs) != 0 {
		return false
	}
	if x.IsPaused {
		return false
	}
	return true
}

func (x DbSyncState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	if len(x.GenVecs) != 0 {
		if err := enc.NextField("GenVecs"); err != nil {
			return err
		}
		if err := x.GenVecs.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.SgGenVecs) != 0 {
		if err := enc.NextField("SgGenVecs"); err != nil {
			return err
		}
		if err := x.SgGenVecs.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.IsPaused {
		if err := enc.NextFieldValueBool("IsPaused", vdl.BoolType, x.IsPaused); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *DbSyncState) VDLRead(dec vdl.Decoder) error {
	*x = DbSyncState{}
	if err := dec.StartValue(__VDLType_struct_2); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "GenVecs":
			if err := x.GenVecs.VDLRead(dec); err != nil {
				return err
			}
		case "SgGenVecs":
			if err := x.SgGenVecs.VDLRead(dec); err != nil {
				return err
			}
		case "IsPaused":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.IsPaused = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// LocalLogRec represents the persistent local state of a log record. Metadata
// is synced across peers, while pos is local-only.
type LocalLogRec struct {
	Metadata interfaces.LogRecMetadata
	Pos      uint64 // position in the Database log.
}

func (LocalLogRec) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/vsync.LocalLogRec"`
}) {
}

func (x LocalLogRec) VDLIsZero() bool {
	if !x.Metadata.VDLIsZero() {
		return false
	}
	if x.Pos != 0 {
		return false
	}
	return true
}

func (x LocalLogRec) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	if !x.Metadata.VDLIsZero() {
		if err := enc.NextField("Metadata"); err != nil {
			return err
		}
		if err := x.Metadata.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Pos != 0 {
		if err := enc.NextFieldValueUint("Pos", vdl.Uint64Type, x.Pos); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *LocalLogRec) VDLRead(dec vdl.Decoder) error {
	*x = LocalLogRec{}
	if err := dec.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Metadata":
			if err := x.Metadata.VDLRead(dec); err != nil {
				return err
			}
		case "Pos":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Pos = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// SgLocalState holds the syncgroup local state, only relevant to this member
// (i.e. the local Syncbase).  This is needed for crash recovery of the internal
// state transitions of the syncgroup.
type SgLocalState struct {
	// The count of local joiners to the same syncgroup.
	NumLocalJoiners uint32
	// The syncgroup is watched when the sync Watcher starts processing the
	// syncgroup data.  When a syncgroup is created or joined, an entry is
	// added to the Watcher queue (log) to inform it from which point to
	// start accepting store mutations, an asynchronous notification similar
	// to regular store mutations.  When the Watcher processes that queue
	// entry, it sets this bit to true.  When Syncbase restarts, the value
	// of this bit allows the new sync Watcher to recreate its in-memory
	// state by resuming to watch only the prefixes of syncgroups that were
	// previously being watched.
	Watched bool
	// The syncgroup was published here by this remote peer (if non-empty
	// string), typically the syncgroup creator.  In this case the syncgroup
	// cannot be GCed locally even if it has no local joiners.
	RemotePublisher string
	// The syncgroup is in pending state on a device that learns the current
	// state of the syncgroup from another device but has not yet received
	// through peer-to-peer sync the history of the changes (DAG and logs).
	// This happens in two cases:
	// 1- A joiner was accepted into a syncgroup by a syncgroup admin and
	//    only given the current syncgroup info synchronously and will
	//    receive the full history later via p2p sync.
	// 2- A remote server where the syncgroup is published was told by the
	//    syncgroup publisher the current syncgroup info synchronously and
	//    will receive the full history later via p2p sync.
	// The pending state is over when the device reaches or exceeds the
	// knowledge level indicated in the pending genvec.  While SyncPending
	// is true, no local syncgroup mutations are allowed (i.e. no join or
	// set-spec requests).
	SyncPending   bool
	PendingGenVec interfaces.GenVector
}

func (SgLocalState) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/vsync.SgLocalState"`
}) {
}

func (x SgLocalState) VDLIsZero() bool {
	if x.NumLocalJoiners != 0 {
		return false
	}
	if x.Watched {
		return false
	}
	if x.RemotePublisher != "" {
		return false
	}
	if x.SyncPending {
		return false
	}
	if len(x.PendingGenVec) != 0 {
		return false
	}
	return true
}

func (x SgLocalState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	if x.NumLocalJoiners != 0 {
		if err := enc.NextFieldValueUint("NumLocalJoiners", vdl.Uint32Type, uint64(x.NumLocalJoiners)); err != nil {
			return err
		}
	}
	if x.Watched {
		if err := enc.NextFieldValueBool("Watched", vdl.BoolType, x.Watched); err != nil {
			return err
		}
	}
	if x.RemotePublisher != "" {
		if err := enc.NextFieldValueString("RemotePublisher", vdl.StringType, x.RemotePublisher); err != nil {
			return err
		}
	}
	if x.SyncPending {
		if err := enc.NextFieldValueBool("SyncPending", vdl.BoolType, x.SyncPending); err != nil {
			return err
		}
	}
	if len(x.PendingGenVec) != 0 {
		if err := enc.NextField("PendingGenVec"); err != nil {
			return err
		}
		if err := x.PendingGenVec.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SgLocalState) VDLRead(dec vdl.Decoder) error {
	*x = SgLocalState{}
	if err := dec.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "NumLocalJoiners":
			switch value, err := dec.ReadValueUint(32); {
			case err != nil:
				return err
			default:
				x.NumLocalJoiners = uint32(value)
			}
		case "Watched":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Watched = value
			}
		case "RemotePublisher":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.RemotePublisher = value
			}
		case "SyncPending":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.SyncPending = value
			}
		case "PendingGenVec":
			if err := x.PendingGenVec.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// DagNode holds the information on an object mutation in the DAG.  The node
// information is extracted from the log records exchanged between Syncbases.
// They are also stored in the DAG node to improve DAG traversal for conflict
// resolution and pruning without having to fetch the full log record.
type DagNode struct {
	Level    uint64   // node distance from root
	Parents  []string // references to parent versions
	Logrec   string   // reference to log record
	BatchId  uint64   // ID of a write batch
	Deleted  bool     // true if the change was a delete
	PermId   string   // ID of the permissions controlling this version
	PermVers string   // current version of the permissions object
}

func (DagNode) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/vsync.DagNode"`
}) {
}

func (x DagNode) VDLIsZero() bool {
	if x.Level != 0 {
		return false
	}
	if len(x.Parents) != 0 {
		return false
	}
	if x.Logrec != "" {
		return false
	}
	if x.BatchId != 0 {
		return false
	}
	if x.Deleted {
		return false
	}
	if x.PermId != "" {
		return false
	}
	if x.PermVers != "" {
		return false
	}
	return true
}

func (x DagNode) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	if x.Level != 0 {
		if err := enc.NextFieldValueUint("Level", vdl.Uint64Type, x.Level); err != nil {
			return err
		}
	}
	if len(x.Parents) != 0 {
		if err := enc.NextField("Parents"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Parents); err != nil {
			return err
		}
	}
	if x.Logrec != "" {
		if err := enc.NextFieldValueString("Logrec", vdl.StringType, x.Logrec); err != nil {
			return err
		}
	}
	if x.BatchId != 0 {
		if err := enc.NextFieldValueUint("BatchId", vdl.Uint64Type, x.BatchId); err != nil {
			return err
		}
	}
	if x.Deleted {
		if err := enc.NextFieldValueBool("Deleted", vdl.BoolType, x.Deleted); err != nil {
			return err
		}
	}
	if x.PermId != "" {
		if err := enc.NextFieldValueString("PermId", vdl.StringType, x.PermId); err != nil {
			return err
		}
	}
	if x.PermVers != "" {
		if err := enc.NextFieldValueString("PermVers", vdl.StringType, x.PermVers); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

func (x *DagNode) VDLRead(dec vdl.Decoder) error {
	*x = DagNode{}
	if err := dec.StartValue(__VDLType_struct_8); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Level":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Level = value
			}
		case "Parents":
			if err := __VDLReadAnon_list_1(dec, &x.Parents); err != nil {
				return err
			}
		case "Logrec":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Logrec = value
			}
		case "BatchId":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.BatchId = value
			}
		case "Deleted":
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Deleted = value
			}
		case "PermId":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.PermId = value
			}
		case "PermVers":
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.PermVers = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

// BatchInfo holds the information on a write batch:
//  * The map of syncable (versioned) objects: {oid: version}
//  * The map of linked objects {oid: version} that were not explicitly written
//    as part of the batch but were reaffirmed during conflict resolution along
//    with other objects written in this batch by the app by choosing
//    "pickLocal" or "pickRemote". NOTE: this map is non empty only for batches
//    created during conflict resolution. Unlike the Objects map, the collection
//    of oid:version present in this map do not point back to this batch. They
//    point to the batches that there were originally created in.
//  * The total count of batch objects, including non-syncable ones.
// TODO(rdaoud): add support to track the read and scan sets.
type BatchInfo struct {
	Objects       map[string]string
	LinkedObjects map[string]string
	Count         uint64
}

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

func (x BatchInfo) VDLIsZero() bool {
	if len(x.Objects) != 0 {
		return false
	}
	if len(x.LinkedObjects) != 0 {
		return false
	}
	if x.Count != 0 {
		return false
	}
	return true
}

func (x BatchInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_10); err != nil {
		return err
	}
	if len(x.Objects) != 0 {
		if err := enc.NextField("Objects"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_2(enc, x.Objects); err != nil {
			return err
		}
	}
	if len(x.LinkedObjects) != 0 {
		if err := enc.NextField("LinkedObjects"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_2(enc, x.LinkedObjects); err != nil {
			return err
		}
	}
	if x.Count != 0 {
		if err := enc.NextFieldValueUint("Count", vdl.Uint64Type, x.Count); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_2(enc vdl.Encoder, x map[string]string) error {
	if err := enc.StartValue(__VDLType_map_11); 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 := enc.WriteValueString(vdl.StringType, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BatchInfo) VDLRead(dec vdl.Decoder) error {
	*x = BatchInfo{}
	if err := dec.StartValue(__VDLType_struct_10); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Objects":
			if err := __VDLReadAnon_map_2(dec, &x.Objects); err != nil {
				return err
			}
		case "LinkedObjects":
			if err := __VDLReadAnon_map_2(dec, &x.LinkedObjects); err != nil {
				return err
			}
		case "Count":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Count = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1  *vdl.Type
	__VDLType_struct_2  *vdl.Type
	__VDLType_map_3     *vdl.Type
	__VDLType_struct_4  *vdl.Type
	__VDLType_struct_5  *vdl.Type
	__VDLType_struct_6  *vdl.Type
	__VDLType_map_7     *vdl.Type
	__VDLType_struct_8  *vdl.Type
	__VDLType_list_9    *vdl.Type
	__VDLType_struct_10 *vdl.Type
	__VDLType_map_11    *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((*SyncData)(nil))
	vdl.Register((*DbSyncState)(nil))
	vdl.Register((*LocalLogRec)(nil))
	vdl.Register((*SgLocalState)(nil))
	vdl.Register((*DagNode)(nil))
	vdl.Register((*BatchInfo)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*SyncData)(nil)).Elem()
	__VDLType_struct_2 = vdl.TypeOf((*DbSyncState)(nil)).Elem()
	__VDLType_map_3 = vdl.TypeOf((*interfaces.Knowledge)(nil))
	__VDLType_struct_4 = vdl.TypeOf((*LocalLogRec)(nil)).Elem()
	__VDLType_struct_5 = vdl.TypeOf((*interfaces.LogRecMetadata)(nil)).Elem()
	__VDLType_struct_6 = vdl.TypeOf((*SgLocalState)(nil)).Elem()
	__VDLType_map_7 = vdl.TypeOf((*interfaces.GenVector)(nil))
	__VDLType_struct_8 = vdl.TypeOf((*DagNode)(nil)).Elem()
	__VDLType_list_9 = vdl.TypeOf((*[]string)(nil))
	__VDLType_struct_10 = vdl.TypeOf((*BatchInfo)(nil)).Elem()
	__VDLType_map_11 = vdl.TypeOf((*map[string]string)(nil))

	return struct{}{}
}
