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

package watchable

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

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

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

// SyncgroupOp represents a change in the set of prefixes that should be tracked
// by sync, i.e. the union of prefix sets across all syncgroups. Note that an
// individual syncgroup's prefixes cannot be changed; this record type is used
// to track changes due to syncgroup create/join/leave/destroy.
type SyncgroupOp struct {
	SgId     interfaces.GroupId
	Prefixes []string
	Remove   bool
}

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

func (x SyncgroupOp) VDLIsZero() bool {
	if x.SgId != "" {
		return false
	}
	if len(x.Prefixes) != 0 {
		return false
	}
	if x.Remove {
		return false
	}
	return true
}

func (x SyncgroupOp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.SgId != "" {
		if err := enc.NextFieldValueString(0, __VDLType_string_2, string(x.SgId)); err != nil {
			return err
		}
	}
	if len(x.Prefixes) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Prefixes); err != nil {
			return err
		}
	}
	if x.Remove {
		if err := enc.NextFieldValueBool(2, vdl.BoolType, x.Remove); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []string) error {
	if err := enc.StartValue(__VDLType_list_3); 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 *SyncgroupOp) VDLRead(dec vdl.Decoder) error {
	*x = SyncgroupOp{}
	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:
				x.SgId = interfaces.GroupId(value)
			}
		case 1:
			if err := __VDLReadAnon_list_1(dec, &x.Prefixes); err != nil {
				return err
			}
		case 2:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Remove = value
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]string) error {
	if err := dec.StartValue(__VDLType_list_3); 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)
		}
	}
}

// SyncSnapshotOp represents a snapshot operation when creating and joining a
// syncgroup. The sync watcher needs to get a snapshot of the Database at the
// point of creating/joining a syncgroup. A SyncSnapshotOp entry is written to
// the log for each Database key that falls within the syncgroup prefixes. This
// allows sync to initialize its metadata at the correct versions of the objects
// when they become syncable. These log entries should be filtered by the
// client-facing Watch interface because the user data did not actually change.
type SyncSnapshotOp struct {
	Key     []byte
	Version []byte
}

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

func (x SyncSnapshotOp) VDLIsZero() bool {
	if len(x.Key) != 0 {
		return false
	}
	if len(x.Version) != 0 {
		return false
	}
	return true
}

func (x SyncSnapshotOp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_4); err != nil {
		return err
	}
	if len(x.Key) != 0 {
		if err := enc.NextFieldValueBytes(0, __VDLType_list_5, x.Key); err != nil {
			return err
		}
	}
	if len(x.Version) != 0 {
		if err := enc.NextFieldValueBytes(1, __VDLType_list_5, x.Version); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SyncSnapshotOp) VDLRead(dec vdl.Decoder) error {
	*x = SyncSnapshotOp{}
	if err := dec.StartValue(__VDLType_struct_4); 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_4 {
			index = __VDLType_struct_4.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := dec.ReadValueBytes(-1, &x.Key); err != nil {
				return err
			}
		case 1:
			if err := dec.ReadValueBytes(-1, &x.Version); err != nil {
				return err
			}
		}
	}
}

// StateChange represents the set of types of state change requests possible.
type StateChange int

const (
	StateChangePauseSync StateChange = iota
	StateChangeResumeSync
)

// StateChangeAll holds all labels for StateChange.
var StateChangeAll = [...]StateChange{StateChangePauseSync, StateChangeResumeSync}

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

// Set assigns label to x.
func (x *StateChange) Set(label string) error {
	switch label {
	case "PauseSync", "pausesync":
		*x = StateChangePauseSync
		return nil
	case "ResumeSync", "resumesync":
		*x = StateChangeResumeSync
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in watchable.StateChange", label)
}

// String returns the string label of x.
func (x StateChange) String() string {
	switch x {
	case StateChangePauseSync:
		return "PauseSync"
	case StateChangeResumeSync:
		return "ResumeSync"
	}
	return ""
}

func (StateChange) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/watchable.StateChange"`
	Enum struct{ PauseSync, ResumeSync string }
}) {
}

func (x StateChange) VDLIsZero() bool {
	return x == StateChangePauseSync
}

func (x StateChange) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_enum_6, x.String()); err != nil {
		return err
	}
	return nil
}

func (x *StateChange) VDLRead(dec vdl.Decoder) error {
	switch value, err := dec.ReadValueString(); {
	case err != nil:
		return err
	default:
		if err := x.Set(value); err != nil {
			return err
		}
	}
	return nil
}

// DbStateChangeRequestOp represents a database state change request.
// Specifically there are two events that create this op:
// PauseSync, indicating a client request to pause sync on this db.
// ResumeSync, indicating a client request to resume sync on this db.
// Client watcher will ignore this op.
type DbStateChangeRequestOp struct {
	RequestType StateChange
}

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

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

func (x DbStateChangeRequestOp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_7); err != nil {
		return err
	}
	if x.RequestType != StateChangePauseSync {
		if err := enc.NextFieldValueString(0, __VDLType_enum_6, x.RequestType.String()); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *DbStateChangeRequestOp) VDLRead(dec vdl.Decoder) error {
	*x = DbStateChangeRequestOp{}
	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:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.RequestType.Set(value); err != nil {
					return err
				}
			}
		}
	}
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1 *vdl.Type
	__VDLType_string_2 *vdl.Type
	__VDLType_list_3   *vdl.Type
	__VDLType_struct_4 *vdl.Type
	__VDLType_list_5   *vdl.Type
	__VDLType_enum_6   *vdl.Type
	__VDLType_struct_7 *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((*SyncgroupOp)(nil))
	vdl.Register((*SyncSnapshotOp)(nil))
	vdl.Register((*StateChange)(nil))
	vdl.Register((*DbStateChangeRequestOp)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*SyncgroupOp)(nil)).Elem()
	__VDLType_string_2 = vdl.TypeOf((*interfaces.GroupId)(nil))
	__VDLType_list_3 = vdl.TypeOf((*[]string)(nil))
	__VDLType_struct_4 = vdl.TypeOf((*SyncSnapshotOp)(nil)).Elem()
	__VDLType_list_5 = vdl.TypeOf((*[]byte)(nil))
	__VDLType_enum_6 = vdl.TypeOf((*StateChange)(nil))
	__VDLType_struct_7 = vdl.TypeOf((*DbStateChangeRequestOp)(nil)).Elem()

	return struct{}{}
}
