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

package interfaces

import (
	"fmt"
	"io"
	"time"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/services/syncbase"
	"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

// GenVector is the generation vector for any syncable entity, which maps each
// device id to its last locally known generation in the scope of that entity.
type GenVector map[uint64]uint64

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

func (x GenVector) VDLIsZero() bool {
	return len(x) == 0
}

func (x GenVector) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_map_1); 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 := enc.WriteValueUint(vdl.Uint64Type, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

// Knowledge is a mapping of syncable entities to their generation
// vectors. These syncable entities could be data prefixes relative to a
// Database id, or syncgroup oids.
type Knowledge map[string]GenVector

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

func (x Knowledge) VDLIsZero() bool {
	return len(x) == 0
}

func (x Knowledge) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_map_2); 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 *Knowledge) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_map_2); err != nil {
		return err
	}
	var tmpMap Knowledge
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(Knowledge, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem GenVector
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(Knowledge)
			}
			tmpMap[key] = elem
		}
	}
}

// LogRecMetadata represents the metadata of a single log record that is
// exchanged between two peers. Each log record represents a change made to an
// object in the store.
//
// TODO(hpucha): Add readset/scanset. Look into sending tx metadata only once
// per transaction.
type LogRecMetadata struct {
	// Log related information.
	Id      uint64 // device id that created the log record.
	Gen     uint64 // generation number for the log record.
	RecType byte   // type of log record.
	// Id of the object that was updated. This id is relative to Application
	// and Database names and is the store key for a particular row in a
	// collection.
	ObjId      string
	CurVers    string    // current version number of the object.
	Parents    []string  // 0, 1 or 2 parent versions that the current version is derived from.
	UpdTime    time.Time // timestamp when the update is generated.
	Delete     bool      // indicates whether the update resulted in object being deleted from the store.
	BatchId    uint64    // unique id of the Batch this update belongs to.
	BatchCount uint64    // number of objects in the Batch.
}

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

func (x LogRecMetadata) VDLIsZero() bool {
	if x.Id != 0 {
		return false
	}
	if x.Gen != 0 {
		return false
	}
	if x.RecType != 0 {
		return false
	}
	if x.ObjId != "" {
		return false
	}
	if x.CurVers != "" {
		return false
	}
	if len(x.Parents) != 0 {
		return false
	}
	if !x.UpdTime.IsZero() {
		return false
	}
	if x.Delete {
		return false
	}
	if x.BatchId != 0 {
		return false
	}
	if x.BatchCount != 0 {
		return false
	}
	return true
}

func (x LogRecMetadata) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	if x.Id != 0 {
		if err := enc.NextFieldValueUint(0, vdl.Uint64Type, x.Id); err != nil {
			return err
		}
	}
	if x.Gen != 0 {
		if err := enc.NextFieldValueUint(1, vdl.Uint64Type, x.Gen); err != nil {
			return err
		}
	}
	if x.RecType != 0 {
		if err := enc.NextFieldValueUint(2, vdl.ByteType, uint64(x.RecType)); err != nil {
			return err
		}
	}
	if x.ObjId != "" {
		if err := enc.NextFieldValueString(3, vdl.StringType, x.ObjId); err != nil {
			return err
		}
	}
	if x.CurVers != "" {
		if err := enc.NextFieldValueString(4, vdl.StringType, x.CurVers); err != nil {
			return err
		}
	}
	if len(x.Parents) != 0 {
		if err := enc.NextField(5); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Parents); err != nil {
			return err
		}
	}
	if !x.UpdTime.IsZero() {
		if err := enc.NextField(6); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.UpdTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Delete {
		if err := enc.NextFieldValueBool(7, vdl.BoolType, x.Delete); err != nil {
			return err
		}
	}
	if x.BatchId != 0 {
		if err := enc.NextFieldValueUint(8, vdl.Uint64Type, x.BatchId); err != nil {
			return err
		}
	}
	if x.BatchCount != 0 {
		if err := enc.NextFieldValueUint(9, vdl.Uint64Type, x.BatchCount); 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_4); 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 *LogRecMetadata) VDLRead(dec vdl.Decoder) error {
	*x = LogRecMetadata{}
	if err := dec.StartValue(__VDLType_struct_3); 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_3 {
			index = __VDLType_struct_3.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.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Id = value
			}
		case 1:
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.Gen = value
			}
		case 2:
			switch value, err := dec.ReadValueUint(8); {
			case err != nil:
				return err
			default:
				x.RecType = byte(value)
			}
		case 3:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.ObjId = value
			}
		case 4:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.CurVers = value
			}
		case 5:
			if err := __VDLReadAnon_list_1(dec, &x.Parents); err != nil {
				return err
			}
		case 6:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.UpdTime); err != nil {
				return err
			}
		case 7:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.Delete = value
			}
		case 8:
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.BatchId = value
			}
		case 9:
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.BatchCount = value
			}
		}
	}
}

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

// LogRec represents the on-wire representation of an entire log record: its
// metadata and data. Value is the actual value of a store object.
type LogRec struct {
	Metadata LogRecMetadata
	Value    *vom.RawBytes
}

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

func (x LogRec) VDLIsZero() bool {
	if !x.Metadata.VDLIsZero() {
		return false
	}
	if x.Value != nil && !x.Value.VDLIsZero() {
		return false
	}
	return true
}

func (x LogRec) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	if !x.Metadata.VDLIsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Metadata.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Value != nil && !x.Value.VDLIsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.Value.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *LogRec) VDLRead(dec vdl.Decoder) error {
	*x = LogRec{
		Value: vom.RawBytesOf(vdl.ZeroValue(vdl.AnyType)),
	}
	if err := dec.StartValue(__VDLType_struct_6); 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_6 {
			index = __VDLType_struct_6.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.Metadata.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			x.Value = new(vom.RawBytes)
			if err := x.Value.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

// GroupId is a globally unique syncgroup ID.
// It is a hash of the syncgroup name.
type GroupId string

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

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

func (x GroupId) VDLWrite(enc vdl.Encoder) error {
	if err := enc.WriteValueString(__VDLType_string_7, string(x)); err != nil {
		return err
	}
	return nil
}

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

// Possible states for a syncgroup.
type SyncgroupStatus int

const (
	SyncgroupStatusPublishPending SyncgroupStatus = iota
	SyncgroupStatusPublishRejected
	SyncgroupStatusRunning
)

// SyncgroupStatusAll holds all labels for SyncgroupStatus.
var SyncgroupStatusAll = [...]SyncgroupStatus{SyncgroupStatusPublishPending, SyncgroupStatusPublishRejected, SyncgroupStatusRunning}

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

// Set assigns label to x.
func (x *SyncgroupStatus) Set(label string) error {
	switch label {
	case "PublishPending", "publishpending":
		*x = SyncgroupStatusPublishPending
		return nil
	case "PublishRejected", "publishrejected":
		*x = SyncgroupStatusPublishRejected
		return nil
	case "Running", "running":
		*x = SyncgroupStatusRunning
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in interfaces.SyncgroupStatus", label)
}

// String returns the string label of x.
func (x SyncgroupStatus) String() string {
	switch x {
	case SyncgroupStatusPublishPending:
		return "PublishPending"
	case SyncgroupStatusPublishRejected:
		return "PublishRejected"
	case SyncgroupStatusRunning:
		return "Running"
	}
	return ""
}

func (SyncgroupStatus) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/server/interfaces.SyncgroupStatus"`
	Enum struct{ PublishPending, PublishRejected, Running string }
}) {
}

func (x SyncgroupStatus) VDLIsZero() bool {
	return x == SyncgroupStatusPublishPending
}

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

func (x *SyncgroupStatus) 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
}

// SyncgroupMemberState contains information about a joiner and the internal bookkeeping
// state required for resolving conflicts on this joiner's join/leave activity.
type SyncgroupMemberState struct {
	// Timestamp of when the member last joined/left the syncgroup. This timestamp is updated
	// even when an existing member rejoins a syncgroup. Represented as Unix time.
	WhenUpdated int64
	// If set then this record indicates that this member has left the group. The SyncgroupMember
	// entry is retained after a delete so that it can be used during conflict resolution, when
	// one node indicates that the member has left the group and another says that the member
	// is still in the group.
	HasLeft bool
	// Information supplied when requesting a join.
	MemberInfo syncbase.SyncgroupMemberInfo
}

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

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

func (x SyncgroupMemberState) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_9); err != nil {
		return err
	}
	if x.WhenUpdated != 0 {
		if err := enc.NextFieldValueInt(0, vdl.Int64Type, x.WhenUpdated); err != nil {
			return err
		}
	}
	if x.HasLeft {
		if err := enc.NextFieldValueBool(1, vdl.BoolType, x.HasLeft); err != nil {
			return err
		}
	}
	if x.MemberInfo != (syncbase.SyncgroupMemberInfo{}) {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := x.MemberInfo.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SyncgroupMemberState) VDLRead(dec vdl.Decoder) error {
	*x = SyncgroupMemberState{}
	if err := dec.StartValue(__VDLType_struct_9); 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_9 {
			index = __VDLType_struct_9.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.ReadValueInt(64); {
			case err != nil:
				return err
			default:
				x.WhenUpdated = value
			}
		case 1:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.HasLeft = value
			}
		case 2:
			if err := x.MemberInfo.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

// Syncgroup contains the state of a syncgroup.
type Syncgroup struct {
	Id          syncbase.Id                     // the relative syncgroup Id chosen by app
	SpecVersion string                          // version on syncgroup spec for concurrency control
	Spec        syncbase.SyncgroupSpec          // app-given specification
	Creator     string                          // Creator's Vanadium name
	DbId        syncbase.Id                     // Globally unique database id
	Status      SyncgroupStatus                 // Status of the syncgroup
	Joiners     map[string]SyncgroupMemberState // map of joiners to their metadata
}

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

func (x Syncgroup) VDLIsZero() bool {
	if x.Id != (syncbase.Id{}) {
		return false
	}
	if x.SpecVersion != "" {
		return false
	}
	if !x.Spec.VDLIsZero() {
		return false
	}
	if x.Creator != "" {
		return false
	}
	if x.DbId != (syncbase.Id{}) {
		return false
	}
	if x.Status != SyncgroupStatusPublishPending {
		return false
	}
	if len(x.Joiners) != 0 {
		return false
	}
	return true
}

func (x Syncgroup) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_11); err != nil {
		return err
	}
	if x.Id != (syncbase.Id{}) {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Id.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.SpecVersion != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.SpecVersion); err != nil {
			return err
		}
	}
	if !x.Spec.VDLIsZero() {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := x.Spec.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Creator != "" {
		if err := enc.NextFieldValueString(3, vdl.StringType, x.Creator); err != nil {
			return err
		}
	}
	if x.DbId != (syncbase.Id{}) {
		if err := enc.NextField(4); err != nil {
			return err
		}
		if err := x.DbId.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Status != SyncgroupStatusPublishPending {
		if err := enc.NextFieldValueString(5, __VDLType_enum_8, x.Status.String()); err != nil {
			return err
		}
	}
	if len(x.Joiners) != 0 {
		if err := enc.NextField(6); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_2(enc, x.Joiners); 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]SyncgroupMemberState) error {
	if err := enc.StartValue(__VDLType_map_14); 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 *Syncgroup) VDLRead(dec vdl.Decoder) error {
	*x = Syncgroup{}
	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 := x.Id.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.SpecVersion = value
			}
		case 2:
			if err := x.Spec.VDLRead(dec); err != nil {
				return err
			}
		case 3:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Creator = value
			}
		case 4:
			if err := x.DbId.VDLRead(dec); err != nil {
				return err
			}
		case 5:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				if err := x.Status.Set(value); err != nil {
					return err
				}
			}
		case 6:
			if err := __VDLReadAnon_map_2(dec, &x.Joiners); err != nil {
				return err
			}
		}
	}
}

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

// CollectionPerms represent the persistent, synced permissions of a Collection.
// Existence of CollectionPerms in the store determines existence of the
// Collection.
// Note: Since CollectionPerms is synced and conflict resolved, the sync
// protocol needs to be aware of it. Any potential additions to synced
// Collection metadata should be written to a separate, synced key prefix,
// written in the same transaction with CollectionPerms and incorporated into
// the sync protocol. All persistent Collection metadata should be synced;
// local-only metadata is acceptable only if optional (e.g. stats).
type CollectionPerms access.Permissions

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

func (x CollectionPerms) VDLIsZero() bool {
	return len(x) == 0
}

func (x CollectionPerms) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_map_15); 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 *CollectionPerms) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_map_15); err != nil {
		return err
	}
	var tmpMap CollectionPerms
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(CollectionPerms, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem access.AccessList
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(CollectionPerms)
			}
			tmpMap[key] = elem
		}
	}
}

// SgDeltaReq contains the initiator's genvectors for the syncgroups it is
// interested in within a database when requesting deltas for those syncgroups.
type SgDeltaReq struct {
	DbId syncbase.Id
	Gvs  Knowledge // Contains a genvector per syncgroup.
}

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

func (x SgDeltaReq) VDLIsZero() bool {
	if x.DbId != (syncbase.Id{}) {
		return false
	}
	if len(x.Gvs) != 0 {
		return false
	}
	return true
}

func (x SgDeltaReq) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_17); err != nil {
		return err
	}
	if x.DbId != (syncbase.Id{}) {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.DbId.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.Gvs) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := x.Gvs.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SgDeltaReq) VDLRead(dec vdl.Decoder) error {
	*x = SgDeltaReq{}
	if err := dec.StartValue(__VDLType_struct_17); 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_17 {
			index = __VDLType_struct_17.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.DbId.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			if err := x.Gvs.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

// DataDeltaReq contains the initiator's genvectors and the set of syncgroups it
// is interested in within a database when requesting deltas for that database.
type DataDeltaReq struct {
	DbId  syncbase.Id
	SgIds map[GroupId]struct{}
	Gvs   Knowledge
}

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

func (x DataDeltaReq) VDLIsZero() bool {
	if x.DbId != (syncbase.Id{}) {
		return false
	}
	if len(x.SgIds) != 0 {
		return false
	}
	if len(x.Gvs) != 0 {
		return false
	}
	return true
}

func (x DataDeltaReq) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_18); err != nil {
		return err
	}
	if x.DbId != (syncbase.Id{}) {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.DbId.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.SgIds) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := __VDLWriteAnon_set_3(enc, x.SgIds); err != nil {
			return err
		}
	}
	if len(x.Gvs) != 0 {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := x.Gvs.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_set_3(enc vdl.Encoder, x map[GroupId]struct{}) error {
	if err := enc.StartValue(__VDLType_set_19); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key := range x {
		if err := enc.NextEntryValueString(__VDLType_string_7, string(key)); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *DataDeltaReq) VDLRead(dec vdl.Decoder) error {
	*x = DataDeltaReq{}
	if err := dec.StartValue(__VDLType_struct_18); 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_18 {
			index = __VDLType_struct_18.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.DbId.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			if err := __VDLReadAnon_set_3(dec, &x.SgIds); err != nil {
				return err
			}
		case 2:
			if err := x.Gvs.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

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

type (
	// DeltaReq represents any single field of the DeltaReq union type.
	//
	// DeltaReq contains a request to sync either data or syncgroup metadata for a
	// Database.
	DeltaReq 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 DeltaReq union type.
		__VDLReflect(__DeltaReqReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// DeltaReqSgs represents field Sgs of the DeltaReq union type.
	DeltaReqSgs struct{ Value SgDeltaReq }
	// DeltaReqData represents field Data of the DeltaReq union type.
	DeltaReqData struct{ Value DataDeltaReq }
	// __DeltaReqReflect describes the DeltaReq union type.
	__DeltaReqReflect struct {
		Name  string `vdl:"v.io/x/ref/services/syncbase/server/interfaces.DeltaReq"`
		Type  DeltaReq
		Union struct {
			Sgs  DeltaReqSgs
			Data DeltaReqData
		}
	}
)

func (x DeltaReqSgs) Index() int                     { return 0 }
func (x DeltaReqSgs) Interface() interface{}         { return x.Value }
func (x DeltaReqSgs) Name() string                   { return "Sgs" }
func (x DeltaReqSgs) __VDLReflect(__DeltaReqReflect) {}

func (x DeltaReqData) Index() int                     { return 1 }
func (x DeltaReqData) Interface() interface{}         { return x.Value }
func (x DeltaReqData) Name() string                   { return "Data" }
func (x DeltaReqData) __VDLReflect(__DeltaReqReflect) {}

func (x DeltaReqSgs) VDLIsZero() bool {
	return x.Value.VDLIsZero()
}

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

func (x DeltaReqSgs) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_20); err != nil {
		return err
	}
	if err := enc.NextField(0); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x DeltaReqData) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_20); err != nil {
		return err
	}
	if err := enc.NextField(1); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadDeltaReq(dec vdl.Decoder, x *DeltaReq) error {
	if err := dec.StartValue(__VDLType_union_20); err != nil {
		return err
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_20 {
		name := decType.Field(index).Name
		index = __VDLType_union_20.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field DeltaReqSgs
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case 1:
		var field DeltaReqData
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, x, dec.Type())
	}
	return dec.FinishValue()
}

type (
	// DeltaResp represents any single field of the DeltaResp union type.
	//
	// DeltaResp contains the responder's genvectors or the missing log records
	// returned in response to an initiator's request for deltas for a Database.
	DeltaResp 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 DeltaResp union type.
		__VDLReflect(__DeltaRespReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// DeltaRespRec represents field Rec of the DeltaResp union type.
	DeltaRespRec struct{ Value LogRec }
	// DeltaRespGvs represents field Gvs of the DeltaResp union type.
	DeltaRespGvs struct{ Value Knowledge }
	// __DeltaRespReflect describes the DeltaResp union type.
	__DeltaRespReflect struct {
		Name  string `vdl:"v.io/x/ref/services/syncbase/server/interfaces.DeltaResp"`
		Type  DeltaResp
		Union struct {
			Rec DeltaRespRec
			Gvs DeltaRespGvs
		}
	}
)

func (x DeltaRespRec) Index() int                      { return 0 }
func (x DeltaRespRec) Interface() interface{}          { return x.Value }
func (x DeltaRespRec) Name() string                    { return "Rec" }
func (x DeltaRespRec) __VDLReflect(__DeltaRespReflect) {}

func (x DeltaRespGvs) Index() int                      { return 1 }
func (x DeltaRespGvs) Interface() interface{}          { return x.Value }
func (x DeltaRespGvs) Name() string                    { return "Gvs" }
func (x DeltaRespGvs) __VDLReflect(__DeltaRespReflect) {}

func (x DeltaRespRec) VDLIsZero() bool {
	return x.Value.VDLIsZero()
}

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

func (x DeltaRespRec) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_21); err != nil {
		return err
	}
	if err := enc.NextField(0); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x DeltaRespGvs) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_21); err != nil {
		return err
	}
	if err := enc.NextField(1); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadDeltaResp(dec vdl.Decoder, x *DeltaResp) error {
	if err := dec.StartValue(__VDLType_union_21); err != nil {
		return err
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_21 {
		name := decType.Field(index).Name
		index = __VDLType_union_21.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field DeltaRespRec
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case 1:
		var field DeltaRespGvs
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, x, dec.Type())
	}
	return dec.FinishValue()
}

// A SgPriority represents data used to decide whether to transfer blob ownership
// between two devices.
type SgPriority struct {
	DevType    int32     // device type (BlobDevTypeServer, BlobDevTypeNormal, BlobDevTypeLeaf)
	Distance   float32   // mean number of hops from a server-quality member of the syncgroup
	ServerTime time.Time // when data from a server-quality member reached this device
}

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

func (x SgPriority) VDLIsZero() bool {
	if x.DevType != 0 {
		return false
	}
	if x.Distance != 0 {
		return false
	}
	if !x.ServerTime.IsZero() {
		return false
	}
	return true
}

func (x SgPriority) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_22); err != nil {
		return err
	}
	if x.DevType != 0 {
		if err := enc.NextFieldValueInt(0, vdl.Int32Type, int64(x.DevType)); err != nil {
			return err
		}
	}
	if x.Distance != 0 {
		if err := enc.NextFieldValueFloat(1, vdl.Float32Type, float64(x.Distance)); err != nil {
			return err
		}
	}
	if !x.ServerTime.IsZero() {
		if err := enc.NextField(2); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.ServerTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SgPriority) VDLRead(dec vdl.Decoder) error {
	*x = SgPriority{}
	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:
			switch value, err := dec.ReadValueInt(32); {
			case err != nil:
				return err
			default:
				x.DevType = int32(value)
			}
		case 1:
			switch value, err := dec.ReadValueFloat(32); {
			case err != nil:
				return err
			default:
				x.Distance = float32(value)
			}
		case 2:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.ServerTime); err != nil {
				return err
			}
		}
	}
}

// A SgPriorities maps syncgroup IDs to SgPriority structures.  It is sent and
// received in GetDeltas calls to allow the participants to assess who has
// higher priorities for keeping blobs.
type SgPriorities map[GroupId]SgPriority

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

func (x SgPriorities) VDLIsZero() bool {
	return len(x) == 0
}

func (x SgPriorities) VDLWrite(enc vdl.Encoder) 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(__VDLType_string_7, string(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 *SgPriorities) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_map_23); err != nil {
		return err
	}
	var tmpMap SgPriorities
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(SgPriorities, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem SgPriority
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(SgPriorities)
			}
			tmpMap[GroupId(key)] = elem
		}
	}
}

// DeltaFinalResp contains the data returned at the end of a GetDeltas call.
type DeltaFinalResp struct {
	SgPriorities SgPriorities
}

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

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

func (x DeltaFinalResp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_24); err != nil {
		return err
	}
	if len(x.SgPriorities) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.SgPriorities.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *DeltaFinalResp) VDLRead(dec vdl.Decoder) error {
	*x = DeltaFinalResp{}
	if err := dec.StartValue(__VDLType_struct_24); 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_24 {
			index = __VDLType_struct_24.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.SgPriorities.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

// ChunkHash contains the hash of a chunk that is part of a blob's recipe.
type ChunkHash struct {
	Hash []byte
}

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

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

func (x ChunkHash) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_25); err != nil {
		return err
	}
	if len(x.Hash) != 0 {
		if err := enc.NextFieldValueBytes(0, __VDLType_list_26, x.Hash); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ChunkHash) VDLRead(dec vdl.Decoder) error {
	*x = ChunkHash{}
	if err := dec.StartValue(__VDLType_struct_25); 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_25 {
			index = __VDLType_struct_25.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.Hash); err != nil {
				return err
			}
		}
	}
}

// ChunkData contains the data of a chunk.
type ChunkData struct {
	Data []byte
}

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

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

func (x ChunkData) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_27); err != nil {
		return err
	}
	if len(x.Data) != 0 {
		if err := enc.NextFieldValueBytes(0, __VDLType_list_26, x.Data); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ChunkData) VDLRead(dec vdl.Decoder) error {
	*x = ChunkData{}
	if err := dec.StartValue(__VDLType_struct_27); 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_27 {
			index = __VDLType_struct_27.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.Data); err != nil {
				return err
			}
		}
	}
}

// TimeReq contains the send timestamp from the requester.
type TimeReq struct {
	SendTs time.Time
}

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

func (x TimeReq) VDLIsZero() bool {
	if !x.SendTs.IsZero() {
		return false
	}
	return true
}

func (x TimeReq) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_28); err != nil {
		return err
	}
	if !x.SendTs.IsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.SendTs); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *TimeReq) VDLRead(dec vdl.Decoder) error {
	*x = TimeReq{}
	if err := dec.StartValue(__VDLType_struct_28); 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_28 {
			index = __VDLType_struct_28.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.SendTs); err != nil {
				return err
			}
		}
	}
}

// TimeResp contains information needed by the requester to estimate the
// difference between the two vclocks and to decide whether to incorporate the
// peer's vclock data.
type TimeResp struct {
	OrigTs time.Time // when we sent request
	RecvTs time.Time // when peer received request
	SendTs time.Time // when peer sent response
	// NTP server timestamp from the most recent NTP sync, or zero value if none.
	// Note, the NTP sync may have been performed by some peer device.
	LastNtpTs time.Time
	// Number of reboots since last NTP sync, accumulated across all hops of p2p
	// clock sync.
	NumReboots uint16
	// Number of sync hops between peer's device and its source of LastNtpTs.
	NumHops uint16
}

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

func (x TimeResp) VDLIsZero() bool {
	if !x.OrigTs.IsZero() {
		return false
	}
	if !x.RecvTs.IsZero() {
		return false
	}
	if !x.SendTs.IsZero() {
		return false
	}
	if !x.LastNtpTs.IsZero() {
		return false
	}
	if x.NumReboots != 0 {
		return false
	}
	if x.NumHops != 0 {
		return false
	}
	return true
}

func (x TimeResp) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_29); err != nil {
		return err
	}
	if !x.OrigTs.IsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.OrigTs); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.RecvTs.IsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.RecvTs); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.SendTs.IsZero() {
		if err := enc.NextField(2); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.SendTs); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.LastNtpTs.IsZero() {
		if err := enc.NextField(3); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.LastNtpTs); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.NumReboots != 0 {
		if err := enc.NextFieldValueUint(4, vdl.Uint16Type, uint64(x.NumReboots)); err != nil {
			return err
		}
	}
	if x.NumHops != 0 {
		if err := enc.NextFieldValueUint(5, vdl.Uint16Type, uint64(x.NumHops)); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *TimeResp) VDLRead(dec vdl.Decoder) error {
	*x = TimeResp{}
	if err := dec.StartValue(__VDLType_struct_29); 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_29 {
			index = __VDLType_struct_29.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.OrigTs); err != nil {
				return err
			}
		case 1:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.RecvTs); 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.SendTs); err != nil {
				return err
			}
		case 3:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.LastNtpTs); err != nil {
				return err
			}
		case 4:
			switch value, err := dec.ReadValueUint(16); {
			case err != nil:
				return err
			default:
				x.NumReboots = uint16(value)
			}
		case 5:
			switch value, err := dec.ReadValueUint(16); {
			case err != nil:
				return err
			default:
				x.NumHops = uint16(value)
			}
		}
	}
}

// A BlobSharesBySyncgroup maps syncgroup IDs to integer share numbers that a
// syncbase instance may have for a blob.
type BlobSharesBySyncgroup map[GroupId]int32

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

func (x BlobSharesBySyncgroup) VDLIsZero() bool {
	return len(x) == 0
}

func (x BlobSharesBySyncgroup) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_map_30); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntryValueString(__VDLType_string_7, string(key)); err != nil {
			return err
		}
		if err := enc.WriteValueInt(vdl.Int32Type, int64(elem)); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *BlobSharesBySyncgroup) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_map_30); err != nil {
		return err
	}
	var tmpMap BlobSharesBySyncgroup
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(BlobSharesBySyncgroup, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem int32
			switch value, err := dec.ReadValueInt(32); {
			case err != nil:
				return err
			default:
				elem = int32(value)
			}
			if tmpMap == nil {
				tmpMap = make(BlobSharesBySyncgroup)
			}
			tmpMap[GroupId(key)] = elem
		}
	}
}

// A LocationData is the information known about a particular location in a Signpost.
// TODO(m3b): Include mount table information to allow the location to be found.
type LocationData struct {
	WhenSeen time.Time // most recent time when blob thought to have been at location
	IsProxy  bool      // whether the location is a likely proxy to another syncgroup
	IsServer bool      // whether the location is a server that may be revealed outside its syncgroup
}

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

func (x LocationData) VDLIsZero() bool {
	if !x.WhenSeen.IsZero() {
		return false
	}
	if x.IsProxy {
		return false
	}
	if x.IsServer {
		return false
	}
	return true
}

func (x LocationData) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_31); err != nil {
		return err
	}
	if !x.WhenSeen.IsZero() {
		if err := enc.NextField(0); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.WhenSeen); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.IsProxy {
		if err := enc.NextFieldValueBool(1, vdl.BoolType, x.IsProxy); err != nil {
			return err
		}
	}
	if x.IsServer {
		if err := enc.NextFieldValueBool(2, vdl.BoolType, x.IsServer); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *LocationData) VDLRead(dec vdl.Decoder) error {
	*x = LocationData{}
	if err := dec.StartValue(__VDLType_struct_31); 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_31 {
			index = __VDLType_struct_31.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.WhenSeen); err != nil {
				return err
			}
		case 1:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.IsProxy = value
			}
		case 2:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.IsServer = value
			}
		}
	}
}

// A PeerToLocationDataMap is a map from syncbase peer names to LocationData structures.
type PeerToLocationDataMap map[string]LocationData

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

func (x PeerToLocationDataMap) VDLIsZero() bool {
	return len(x) == 0
}

func (x PeerToLocationDataMap) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_map_32); 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 *PeerToLocationDataMap) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(__VDLType_map_32); err != nil {
		return err
	}
	var tmpMap PeerToLocationDataMap
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(PeerToLocationDataMap, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem LocationData
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(PeerToLocationDataMap)
			}
			tmpMap[key] = elem
		}
	}
}

// A Signpost is a hint to syncbase of the device on which a blob may be found.
// It represents the data known about a blob even when the blob itself is not
// present on the device.
type Signpost struct {
	Locations     PeerToLocationDataMap // Maps name of syncbase that probably has the blob to a LocationData
	SgIds         map[GroupId]struct{}  // SyncGroups through which the BlobRef was learned.
	FetchAttempts uint32                // Number of attempts made to fetch the blob.
}

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

func (x Signpost) VDLIsZero() bool {
	if len(x.Locations) != 0 {
		return false
	}
	if len(x.SgIds) != 0 {
		return false
	}
	if x.FetchAttempts != 0 {
		return false
	}
	return true
}

func (x Signpost) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_33); err != nil {
		return err
	}
	if len(x.Locations) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := x.Locations.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.SgIds) != 0 {
		if err := enc.NextField(1); err != nil {
			return err
		}
		if err := __VDLWriteAnon_set_3(enc, x.SgIds); err != nil {
			return err
		}
	}
	if x.FetchAttempts != 0 {
		if err := enc.NextFieldValueUint(2, vdl.Uint32Type, uint64(x.FetchAttempts)); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Signpost) VDLRead(dec vdl.Decoder) error {
	*x = Signpost{}
	if err := dec.StartValue(__VDLType_struct_33); 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_33 {
			index = __VDLType_struct_33.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := x.Locations.VDLRead(dec); err != nil {
				return err
			}
		case 1:
			if err := __VDLReadAnon_set_3(dec, &x.SgIds); err != nil {
				return err
			}
		case 2:
			switch value, err := dec.ReadValueUint(32); {
			case err != nil:
				return err
			default:
				x.FetchAttempts = uint32(value)
			}
		}
	}
}

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

const NoGroupId = GroupId("")

// NodeRec type log record adds a new node in the dag.
const NodeRec = byte(0)

// LinkRec type log record adds a new link in the dag. Link records are
// added when a conflict is resolved by picking the local or the remote
// version as the resolution of a conflict, instead of creating a new
// version.
const LinkRec = byte(1)

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

var (
	ErrDupSyncgroupPublish = verror.Register("v.io/x/ref/services/syncbase/server/interfaces.DupSyncgroupPublish", verror.NoRetry, "{1:}{2:} duplicate publish on syncgroup: {3}")
	ErrConnFail            = verror.Register("v.io/x/ref/services/syncbase/server/interfaces.ConnFail", verror.NoRetry, "{1:}{2:} connection to peer failed{:_}")
	ErrBrokenCrConnection  = verror.Register("v.io/x/ref/services/syncbase/server/interfaces.BrokenCrConnection", verror.NoRetry, "{1:}{2:} CrConnection stream to client does not exist or is broken")
	ErrDbOffline           = verror.Register("v.io/x/ref/services/syncbase/server/interfaces.DbOffline", verror.NoRetry, "{1:}{2:} database {3} is offline and cannot be synced{:_}")
	ErrGetTimeFailed       = verror.Register("v.io/x/ref/services/syncbase/server/interfaces.GetTimeFailed", verror.NoRetry, "{1:}{2:} GetTime failed{:_}")
	ErrNotAdmin            = verror.Register("v.io/x/ref/services/syncbase/server/interfaces.NotAdmin", verror.NoRetry, "{1:}{2:} not an admin of the syncgroup")
)

// NewErrDupSyncgroupPublish returns an error with the ErrDupSyncgroupPublish ID.
func NewErrDupSyncgroupPublish(ctx *context.T, sgId syncbase.Id) error {
	return verror.New(ErrDupSyncgroupPublish, ctx, sgId)
}

// NewErrConnFail returns an error with the ErrConnFail ID.
func NewErrConnFail(ctx *context.T) error {
	return verror.New(ErrConnFail, ctx)
}

// NewErrBrokenCrConnection returns an error with the ErrBrokenCrConnection ID.
func NewErrBrokenCrConnection(ctx *context.T) error {
	return verror.New(ErrBrokenCrConnection, ctx)
}

// NewErrDbOffline returns an error with the ErrDbOffline ID.
func NewErrDbOffline(ctx *context.T, dbId syncbase.Id) error {
	return verror.New(ErrDbOffline, ctx, dbId)
}

// NewErrGetTimeFailed returns an error with the ErrGetTimeFailed ID.
func NewErrGetTimeFailed(ctx *context.T) error {
	return verror.New(ErrGetTimeFailed, ctx)
}

// NewErrNotAdmin returns an error with the ErrNotAdmin ID.
func NewErrNotAdmin(ctx *context.T) error {
	return verror.New(ErrNotAdmin, ctx)
}

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

// SyncClientMethods is the client interface
// containing Sync methods.
//
// Sync defines methods for data exchange between Syncbases.
// TODO(hpucha): Flesh this out further.
type SyncClientMethods interface {
	// GetTime returns metadata related to the Syncbase virtual clock, including
	// system clock values, last NTP timestamp, num reboots, etc.
	GetTime(_ *context.T, req TimeReq, initiator string, _ ...rpc.CallOpt) (TimeResp, error)
	// GetDeltas returns the responder's current generation vectors and all
	// the missing log records when compared to the initiator's generation
	// vectors for one Database for either syncgroup metadata or data.
	// The final result (in DeltaFinalResp) currently includes the
	// syncgroup priorities for blob ownership for the server.
	GetDeltas(_ *context.T, req DeltaReq, initiator string, _ ...rpc.CallOpt) (SyncGetDeltasClientCall, error)
	// PublishSyncgroup is invoked on the syncgroup name (typically served
	// by a "central" peer) to publish the syncgroup.  It takes the name of
	// Syncbase doing the publishing (the publisher) and returns the name
	// of the Syncbase where the syncgroup is published (the publishee).
	// This allows the publisher and the publishee to learn of each other.
	// When a syncgroup is published, the publishee is given the syncgroup
	// metadata, its current version at the publisher, and the current
	// syncgroup generation vector.  The generation vector serves as a
	// checkpoint at the time of publishing.  The publishing proceeds
	// asynchronously, and the publishee learns the syncgroup history
	// through the routine p2p sync process and determines when it has
	// caught up to the level of knowledge at the time of publishing using
	// the checkpointed generation vector.  Until that point, the publishee
	// locally deems the syncgroup to be in a pending state and does not
	// mutate it.  Thus it locally rejects syncgroup joins or updates to
	// its spec until it is caught up on the syncgroup history.
	PublishSyncgroup(_ *context.T, publisher string, sg Syncgroup, version string, genvec GenVector, _ ...rpc.CallOpt) (string, error)
	// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's
	// Syncbase on a syncgroup admin. It checks whether the requestor is
	// allowed to join the named syncgroup, and if so, adds the requestor to
	// the syncgroup.  It returns a copy of the updated syncgroup metadata,
	// its version, and the syncgroup generation vector at the time of the
	// join.  Similar to the PublishSyncgroup scenario, the joiner at that
	// point does not have the syncgroup history and locally deems it to be
	// in a pending state and does not mutate it.  This means it rejects
	// local updates to the syncgroup spec or, if it were also an admin on
	// the syncgroup, it would reject syncgroup joins until it is caught up
	// on the syncgroup history through p2p sync.
	JoinSyncgroupAtAdmin(_ *context.T, dbId syncbase.Id, sgId syncbase.Id, joinerName string, myInfo syncbase.SyncgroupMemberInfo, _ ...rpc.CallOpt) (sg Syncgroup, version string, genvec GenVector, _ error)
	// HaveBlob verifies that the peer has the requested blob, and if
	// present, returns its size.  Otherwise, it returns -1, and the location
	// hints (the Signpost) that the peer has for the blob, filtered to
	// include only data the caller is permitted to see:
	// + Device D reveals a syncgroup SG to the caller C iff
	//   - D is in SG, and
	//   - SG is in the Signpost, and
	//   - at least one of:
	//     - SG is not private, or
	//     - C has permission to join SG.
	// + Device D reveals a location hint L to caller C iff
	//   there is a syncgroup SG such that
	//   - D is in SG, and
	//   - SG is in the Signpost, and
	//   - L is in SG, and
	//   - at least one of:
	//     - SG is not private, or
	//     - C has permission to join SG, or
	//     - L is a blob server in SG.
	HaveBlob(_ *context.T, br syncbase.BlobRef, _ ...rpc.CallOpt) (size int64, signpost Signpost, _ error)
	// FetchBlob fetches the requested blob.
	// It returns a number of blob ownership shares that the server hopes
	// the client will accept using the AcceptedBlobOwnership() call.
	FetchBlob(_ *context.T, br syncbase.BlobRef, mySgPriorities SgPriorities, _ ...rpc.CallOpt) (SyncFetchBlobClientCall, error)
	// Methods for incremental blob transfer. The transfer starts with the
	// receiver making a FetchBlobRecipe call to the sender for a given
	// BlobRef. The sender, in turn, sends the chunk hashes of all the
	// chunks that make up the requested blob (blob recipe). The receiver
	// looks up the chunk hashes in its local blob store, and identifies the
	// missing ones. The receiver then fetches the missing chunks using a
	// FetchChunks call from the sender. Finally, the receiver finishes the
	// blob fetch by combining the chunks obtained over the network with the
	// already available local chunks as per the blob recipe.
	// callerName is the syncbase Id of the caller, expressed as a string.
	// FetchBlobRecipe returns a number of blob ownership shares that the
	// server hopes the client will accept for each syncgroup using the
	// AcceptedBlobOwnership() call.
	FetchBlobRecipe(_ *context.T, br syncbase.BlobRef, callerName string, mySgPriorities SgPriorities, _ ...rpc.CallOpt) (SyncFetchBlobRecipeClientCall, error)
	FetchChunks(*context.T, ...rpc.CallOpt) (SyncFetchChunksClientCall, error)
	// RequestTakeBlob indicates that the caller wishes the server to take
	// some blob ownership shares for various syncgroups for the specified blob.
	// If the server chooses to act on the request, it may call FetchBlob/FetchBlobRecipe,
	// and ultimately AcceptedBlobOwnership().
	// callerName is the syncbase Id of the caller, expressed as a string.
	RequestTakeBlob(_ *context.T, br syncbase.BlobRef, callerName string, shares BlobSharesBySyncgroup, _ ...rpc.CallOpt) error
	// AcceptedBlobOwnership tells the server that the client callerName (a
	// syncbase Id expressed as a string) has accepted blob ownership of a
	// specified number of shares for blob br.  The server may decrement
	// its share count by up to this number.  It is safe for the server to
	// decrement its share count by fewer than the number of shares another
	// device has taken responsibility for, but unsafe to decrement it by
	// more than that that number.  It returns a hint as to whether the
	// server is likely to keep the blob itself, plus its syncbase Id
	// expressed as a string.
	AcceptedBlobOwnership(_ *context.T, br syncbase.BlobRef, callerName string, shares BlobSharesBySyncgroup, _ ...rpc.CallOpt) (serverName string, keepingBlob bool, _ error)
}

// SyncClientStub adds universal methods to SyncClientMethods.
type SyncClientStub interface {
	SyncClientMethods
	rpc.UniversalServiceMethods
}

// SyncClient returns a client stub for Sync.
func SyncClient(name string) SyncClientStub {
	return implSyncClientStub{name}
}

type implSyncClientStub struct {
	name string
}

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

func (c implSyncClientStub) GetDeltas(ctx *context.T, i0 DeltaReq, i1 string, opts ...rpc.CallOpt) (ocall SyncGetDeltasClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "GetDeltas", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implSyncGetDeltasClientCall{ClientCall: call}
	return
}

func (c implSyncClientStub) PublishSyncgroup(ctx *context.T, i0 string, i1 Syncgroup, i2 string, i3 GenVector, opts ...rpc.CallOpt) (o0 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "PublishSyncgroup", []interface{}{i0, i1, i2, i3}, []interface{}{&o0}, opts...)
	return
}

func (c implSyncClientStub) JoinSyncgroupAtAdmin(ctx *context.T, i0 syncbase.Id, i1 syncbase.Id, i2 string, i3 syncbase.SyncgroupMemberInfo, opts ...rpc.CallOpt) (o0 Syncgroup, o1 string, o2 GenVector, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "JoinSyncgroupAtAdmin", []interface{}{i0, i1, i2, i3}, []interface{}{&o0, &o1, &o2}, opts...)
	return
}

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

func (c implSyncClientStub) FetchBlob(ctx *context.T, i0 syncbase.BlobRef, i1 SgPriorities, opts ...rpc.CallOpt) (ocall SyncFetchBlobClientCall, 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 = &implSyncFetchBlobClientCall{ClientCall: call}
	return
}

func (c implSyncClientStub) FetchBlobRecipe(ctx *context.T, i0 syncbase.BlobRef, i1 string, i2 SgPriorities, opts ...rpc.CallOpt) (ocall SyncFetchBlobRecipeClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "FetchBlobRecipe", []interface{}{i0, i1, i2}, opts...); err != nil {
		return
	}
	ocall = &implSyncFetchBlobRecipeClientCall{ClientCall: call}
	return
}

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

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

func (c implSyncClientStub) AcceptedBlobOwnership(ctx *context.T, i0 syncbase.BlobRef, i1 string, i2 BlobSharesBySyncgroup, opts ...rpc.CallOpt) (o0 string, o1 bool, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "AcceptedBlobOwnership", []interface{}{i0, i1, i2}, []interface{}{&o0, &o1}, opts...)
	return
}

// SyncGetDeltasClientStream is the client stream for Sync.GetDeltas.
type SyncGetDeltasClientStream interface {
	// RecvStream returns the receiver side of the Sync.GetDeltas 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() DeltaResp
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// SyncGetDeltasClientCall represents the call returned from Sync.GetDeltas.
type SyncGetDeltasClientCall interface {
	SyncGetDeltasClientStream
	// 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() (DeltaFinalResp, error)
}

type implSyncGetDeltasClientCall struct {
	rpc.ClientCall
	valRecv DeltaResp
	errRecv error
}

func (c *implSyncGetDeltasClientCall) RecvStream() interface {
	Advance() bool
	Value() DeltaResp
	Err() error
} {
	return implSyncGetDeltasClientCallRecv{c}
}

type implSyncGetDeltasClientCallRecv struct {
	c *implSyncGetDeltasClientCall
}

func (c implSyncGetDeltasClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implSyncGetDeltasClientCallRecv) Value() DeltaResp {
	return c.c.valRecv
}
func (c implSyncGetDeltasClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implSyncGetDeltasClientCall) Finish() (o0 DeltaFinalResp, err error) {
	err = c.ClientCall.Finish(&o0)
	return
}

// SyncFetchBlobClientStream is the client stream for Sync.FetchBlob.
type SyncFetchBlobClientStream interface {
	// RecvStream returns the receiver side of the Sync.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() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// SyncFetchBlobClientCall represents the call returned from Sync.FetchBlob.
type SyncFetchBlobClientCall interface {
	SyncFetchBlobClientStream
	// 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() (shares BlobSharesBySyncgroup, _ error)
}

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

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

type implSyncFetchBlobClientCallRecv struct {
	c *implSyncFetchBlobClientCall
}

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

// SyncFetchBlobRecipeClientStream is the client stream for Sync.FetchBlobRecipe.
type SyncFetchBlobRecipeClientStream interface {
	// RecvStream returns the receiver side of the Sync.FetchBlobRecipe 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() ChunkHash
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// SyncFetchBlobRecipeClientCall represents the call returned from Sync.FetchBlobRecipe.
type SyncFetchBlobRecipeClientCall interface {
	SyncFetchBlobRecipeClientStream
	// 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() (shares BlobSharesBySyncgroup, _ error)
}

type implSyncFetchBlobRecipeClientCall struct {
	rpc.ClientCall
	valRecv ChunkHash
	errRecv error
}

func (c *implSyncFetchBlobRecipeClientCall) RecvStream() interface {
	Advance() bool
	Value() ChunkHash
	Err() error
} {
	return implSyncFetchBlobRecipeClientCallRecv{c}
}

type implSyncFetchBlobRecipeClientCallRecv struct {
	c *implSyncFetchBlobRecipeClientCall
}

func (c implSyncFetchBlobRecipeClientCallRecv) Advance() bool {
	c.c.valRecv = ChunkHash{}
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implSyncFetchBlobRecipeClientCallRecv) Value() ChunkHash {
	return c.c.valRecv
}
func (c implSyncFetchBlobRecipeClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implSyncFetchBlobRecipeClientCall) Finish() (o0 BlobSharesBySyncgroup, err error) {
	err = c.ClientCall.Finish(&o0)
	return
}

// SyncFetchChunksClientStream is the client stream for Sync.FetchChunks.
type SyncFetchChunksClientStream interface {
	// RecvStream returns the receiver side of the Sync.FetchChunks 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() ChunkData
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Sync.FetchChunks 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 ChunkHash) 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
	}
}

// SyncFetchChunksClientCall represents the call returned from Sync.FetchChunks.
type SyncFetchChunksClientCall interface {
	SyncFetchChunksClientStream
	// 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 implSyncFetchChunksClientCall struct {
	rpc.ClientCall
	valRecv ChunkData
	errRecv error
}

func (c *implSyncFetchChunksClientCall) RecvStream() interface {
	Advance() bool
	Value() ChunkData
	Err() error
} {
	return implSyncFetchChunksClientCallRecv{c}
}

type implSyncFetchChunksClientCallRecv struct {
	c *implSyncFetchChunksClientCall
}

func (c implSyncFetchChunksClientCallRecv) Advance() bool {
	c.c.valRecv = ChunkData{}
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implSyncFetchChunksClientCallRecv) Value() ChunkData {
	return c.c.valRecv
}
func (c implSyncFetchChunksClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implSyncFetchChunksClientCall) SendStream() interface {
	Send(item ChunkHash) error
	Close() error
} {
	return implSyncFetchChunksClientCallSend{c}
}

type implSyncFetchChunksClientCallSend struct {
	c *implSyncFetchChunksClientCall
}

func (c implSyncFetchChunksClientCallSend) Send(item ChunkHash) error {
	return c.c.Send(item)
}
func (c implSyncFetchChunksClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implSyncFetchChunksClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// SyncServerMethods is the interface a server writer
// implements for Sync.
//
// Sync defines methods for data exchange between Syncbases.
// TODO(hpucha): Flesh this out further.
type SyncServerMethods interface {
	// GetTime returns metadata related to the Syncbase virtual clock, including
	// system clock values, last NTP timestamp, num reboots, etc.
	GetTime(_ *context.T, _ rpc.ServerCall, req TimeReq, initiator string) (TimeResp, error)
	// GetDeltas returns the responder's current generation vectors and all
	// the missing log records when compared to the initiator's generation
	// vectors for one Database for either syncgroup metadata or data.
	// The final result (in DeltaFinalResp) currently includes the
	// syncgroup priorities for blob ownership for the server.
	GetDeltas(_ *context.T, _ SyncGetDeltasServerCall, req DeltaReq, initiator string) (DeltaFinalResp, error)
	// PublishSyncgroup is invoked on the syncgroup name (typically served
	// by a "central" peer) to publish the syncgroup.  It takes the name of
	// Syncbase doing the publishing (the publisher) and returns the name
	// of the Syncbase where the syncgroup is published (the publishee).
	// This allows the publisher and the publishee to learn of each other.
	// When a syncgroup is published, the publishee is given the syncgroup
	// metadata, its current version at the publisher, and the current
	// syncgroup generation vector.  The generation vector serves as a
	// checkpoint at the time of publishing.  The publishing proceeds
	// asynchronously, and the publishee learns the syncgroup history
	// through the routine p2p sync process and determines when it has
	// caught up to the level of knowledge at the time of publishing using
	// the checkpointed generation vector.  Until that point, the publishee
	// locally deems the syncgroup to be in a pending state and does not
	// mutate it.  Thus it locally rejects syncgroup joins or updates to
	// its spec until it is caught up on the syncgroup history.
	PublishSyncgroup(_ *context.T, _ rpc.ServerCall, publisher string, sg Syncgroup, version string, genvec GenVector) (string, error)
	// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's
	// Syncbase on a syncgroup admin. It checks whether the requestor is
	// allowed to join the named syncgroup, and if so, adds the requestor to
	// the syncgroup.  It returns a copy of the updated syncgroup metadata,
	// its version, and the syncgroup generation vector at the time of the
	// join.  Similar to the PublishSyncgroup scenario, the joiner at that
	// point does not have the syncgroup history and locally deems it to be
	// in a pending state and does not mutate it.  This means it rejects
	// local updates to the syncgroup spec or, if it were also an admin on
	// the syncgroup, it would reject syncgroup joins until it is caught up
	// on the syncgroup history through p2p sync.
	JoinSyncgroupAtAdmin(_ *context.T, _ rpc.ServerCall, dbId syncbase.Id, sgId syncbase.Id, joinerName string, myInfo syncbase.SyncgroupMemberInfo) (sg Syncgroup, version string, genvec GenVector, _ error)
	// HaveBlob verifies that the peer has the requested blob, and if
	// present, returns its size.  Otherwise, it returns -1, and the location
	// hints (the Signpost) that the peer has for the blob, filtered to
	// include only data the caller is permitted to see:
	// + Device D reveals a syncgroup SG to the caller C iff
	//   - D is in SG, and
	//   - SG is in the Signpost, and
	//   - at least one of:
	//     - SG is not private, or
	//     - C has permission to join SG.
	// + Device D reveals a location hint L to caller C iff
	//   there is a syncgroup SG such that
	//   - D is in SG, and
	//   - SG is in the Signpost, and
	//   - L is in SG, and
	//   - at least one of:
	//     - SG is not private, or
	//     - C has permission to join SG, or
	//     - L is a blob server in SG.
	HaveBlob(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef) (size int64, signpost Signpost, _ error)
	// FetchBlob fetches the requested blob.
	// It returns a number of blob ownership shares that the server hopes
	// the client will accept using the AcceptedBlobOwnership() call.
	FetchBlob(_ *context.T, _ SyncFetchBlobServerCall, br syncbase.BlobRef, mySgPriorities SgPriorities) (shares BlobSharesBySyncgroup, _ error)
	// Methods for incremental blob transfer. The transfer starts with the
	// receiver making a FetchBlobRecipe call to the sender for a given
	// BlobRef. The sender, in turn, sends the chunk hashes of all the
	// chunks that make up the requested blob (blob recipe). The receiver
	// looks up the chunk hashes in its local blob store, and identifies the
	// missing ones. The receiver then fetches the missing chunks using a
	// FetchChunks call from the sender. Finally, the receiver finishes the
	// blob fetch by combining the chunks obtained over the network with the
	// already available local chunks as per the blob recipe.
	// callerName is the syncbase Id of the caller, expressed as a string.
	// FetchBlobRecipe returns a number of blob ownership shares that the
	// server hopes the client will accept for each syncgroup using the
	// AcceptedBlobOwnership() call.
	FetchBlobRecipe(_ *context.T, _ SyncFetchBlobRecipeServerCall, br syncbase.BlobRef, callerName string, mySgPriorities SgPriorities) (shares BlobSharesBySyncgroup, _ error)
	FetchChunks(*context.T, SyncFetchChunksServerCall) error
	// RequestTakeBlob indicates that the caller wishes the server to take
	// some blob ownership shares for various syncgroups for the specified blob.
	// If the server chooses to act on the request, it may call FetchBlob/FetchBlobRecipe,
	// and ultimately AcceptedBlobOwnership().
	// callerName is the syncbase Id of the caller, expressed as a string.
	RequestTakeBlob(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef, callerName string, shares BlobSharesBySyncgroup) error
	// AcceptedBlobOwnership tells the server that the client callerName (a
	// syncbase Id expressed as a string) has accepted blob ownership of a
	// specified number of shares for blob br.  The server may decrement
	// its share count by up to this number.  It is safe for the server to
	// decrement its share count by fewer than the number of shares another
	// device has taken responsibility for, but unsafe to decrement it by
	// more than that that number.  It returns a hint as to whether the
	// server is likely to keep the blob itself, plus its syncbase Id
	// expressed as a string.
	AcceptedBlobOwnership(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef, callerName string, shares BlobSharesBySyncgroup) (serverName string, keepingBlob bool, _ error)
}

// SyncServerStubMethods is the server interface containing
// Sync methods, as expected by rpc.Server.
// The only difference between this interface and SyncServerMethods
// is the streaming methods.
type SyncServerStubMethods interface {
	// GetTime returns metadata related to the Syncbase virtual clock, including
	// system clock values, last NTP timestamp, num reboots, etc.
	GetTime(_ *context.T, _ rpc.ServerCall, req TimeReq, initiator string) (TimeResp, error)
	// GetDeltas returns the responder's current generation vectors and all
	// the missing log records when compared to the initiator's generation
	// vectors for one Database for either syncgroup metadata or data.
	// The final result (in DeltaFinalResp) currently includes the
	// syncgroup priorities for blob ownership for the server.
	GetDeltas(_ *context.T, _ *SyncGetDeltasServerCallStub, req DeltaReq, initiator string) (DeltaFinalResp, error)
	// PublishSyncgroup is invoked on the syncgroup name (typically served
	// by a "central" peer) to publish the syncgroup.  It takes the name of
	// Syncbase doing the publishing (the publisher) and returns the name
	// of the Syncbase where the syncgroup is published (the publishee).
	// This allows the publisher and the publishee to learn of each other.
	// When a syncgroup is published, the publishee is given the syncgroup
	// metadata, its current version at the publisher, and the current
	// syncgroup generation vector.  The generation vector serves as a
	// checkpoint at the time of publishing.  The publishing proceeds
	// asynchronously, and the publishee learns the syncgroup history
	// through the routine p2p sync process and determines when it has
	// caught up to the level of knowledge at the time of publishing using
	// the checkpointed generation vector.  Until that point, the publishee
	// locally deems the syncgroup to be in a pending state and does not
	// mutate it.  Thus it locally rejects syncgroup joins or updates to
	// its spec until it is caught up on the syncgroup history.
	PublishSyncgroup(_ *context.T, _ rpc.ServerCall, publisher string, sg Syncgroup, version string, genvec GenVector) (string, error)
	// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's
	// Syncbase on a syncgroup admin. It checks whether the requestor is
	// allowed to join the named syncgroup, and if so, adds the requestor to
	// the syncgroup.  It returns a copy of the updated syncgroup metadata,
	// its version, and the syncgroup generation vector at the time of the
	// join.  Similar to the PublishSyncgroup scenario, the joiner at that
	// point does not have the syncgroup history and locally deems it to be
	// in a pending state and does not mutate it.  This means it rejects
	// local updates to the syncgroup spec or, if it were also an admin on
	// the syncgroup, it would reject syncgroup joins until it is caught up
	// on the syncgroup history through p2p sync.
	JoinSyncgroupAtAdmin(_ *context.T, _ rpc.ServerCall, dbId syncbase.Id, sgId syncbase.Id, joinerName string, myInfo syncbase.SyncgroupMemberInfo) (sg Syncgroup, version string, genvec GenVector, _ error)
	// HaveBlob verifies that the peer has the requested blob, and if
	// present, returns its size.  Otherwise, it returns -1, and the location
	// hints (the Signpost) that the peer has for the blob, filtered to
	// include only data the caller is permitted to see:
	// + Device D reveals a syncgroup SG to the caller C iff
	//   - D is in SG, and
	//   - SG is in the Signpost, and
	//   - at least one of:
	//     - SG is not private, or
	//     - C has permission to join SG.
	// + Device D reveals a location hint L to caller C iff
	//   there is a syncgroup SG such that
	//   - D is in SG, and
	//   - SG is in the Signpost, and
	//   - L is in SG, and
	//   - at least one of:
	//     - SG is not private, or
	//     - C has permission to join SG, or
	//     - L is a blob server in SG.
	HaveBlob(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef) (size int64, signpost Signpost, _ error)
	// FetchBlob fetches the requested blob.
	// It returns a number of blob ownership shares that the server hopes
	// the client will accept using the AcceptedBlobOwnership() call.
	FetchBlob(_ *context.T, _ *SyncFetchBlobServerCallStub, br syncbase.BlobRef, mySgPriorities SgPriorities) (shares BlobSharesBySyncgroup, _ error)
	// Methods for incremental blob transfer. The transfer starts with the
	// receiver making a FetchBlobRecipe call to the sender for a given
	// BlobRef. The sender, in turn, sends the chunk hashes of all the
	// chunks that make up the requested blob (blob recipe). The receiver
	// looks up the chunk hashes in its local blob store, and identifies the
	// missing ones. The receiver then fetches the missing chunks using a
	// FetchChunks call from the sender. Finally, the receiver finishes the
	// blob fetch by combining the chunks obtained over the network with the
	// already available local chunks as per the blob recipe.
	// callerName is the syncbase Id of the caller, expressed as a string.
	// FetchBlobRecipe returns a number of blob ownership shares that the
	// server hopes the client will accept for each syncgroup using the
	// AcceptedBlobOwnership() call.
	FetchBlobRecipe(_ *context.T, _ *SyncFetchBlobRecipeServerCallStub, br syncbase.BlobRef, callerName string, mySgPriorities SgPriorities) (shares BlobSharesBySyncgroup, _ error)
	FetchChunks(*context.T, *SyncFetchChunksServerCallStub) error
	// RequestTakeBlob indicates that the caller wishes the server to take
	// some blob ownership shares for various syncgroups for the specified blob.
	// If the server chooses to act on the request, it may call FetchBlob/FetchBlobRecipe,
	// and ultimately AcceptedBlobOwnership().
	// callerName is the syncbase Id of the caller, expressed as a string.
	RequestTakeBlob(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef, callerName string, shares BlobSharesBySyncgroup) error
	// AcceptedBlobOwnership tells the server that the client callerName (a
	// syncbase Id expressed as a string) has accepted blob ownership of a
	// specified number of shares for blob br.  The server may decrement
	// its share count by up to this number.  It is safe for the server to
	// decrement its share count by fewer than the number of shares another
	// device has taken responsibility for, but unsafe to decrement it by
	// more than that that number.  It returns a hint as to whether the
	// server is likely to keep the blob itself, plus its syncbase Id
	// expressed as a string.
	AcceptedBlobOwnership(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef, callerName string, shares BlobSharesBySyncgroup) (serverName string, keepingBlob bool, _ error)
}

// SyncServerStub adds universal methods to SyncServerStubMethods.
type SyncServerStub interface {
	SyncServerStubMethods
	// Describe the Sync interfaces.
	Describe__() []rpc.InterfaceDesc
}

// SyncServer returns a server stub for Sync.
// It converts an implementation of SyncServerMethods into
// an object that may be used by rpc.Server.
func SyncServer(impl SyncServerMethods) SyncServerStub {
	stub := implSyncServerStub{
		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 implSyncServerStub struct {
	impl SyncServerMethods
	gs   *rpc.GlobState
}

func (s implSyncServerStub) GetTime(ctx *context.T, call rpc.ServerCall, i0 TimeReq, i1 string) (TimeResp, error) {
	return s.impl.GetTime(ctx, call, i0, i1)
}

func (s implSyncServerStub) GetDeltas(ctx *context.T, call *SyncGetDeltasServerCallStub, i0 DeltaReq, i1 string) (DeltaFinalResp, error) {
	return s.impl.GetDeltas(ctx, call, i0, i1)
}

func (s implSyncServerStub) PublishSyncgroup(ctx *context.T, call rpc.ServerCall, i0 string, i1 Syncgroup, i2 string, i3 GenVector) (string, error) {
	return s.impl.PublishSyncgroup(ctx, call, i0, i1, i2, i3)
}

func (s implSyncServerStub) JoinSyncgroupAtAdmin(ctx *context.T, call rpc.ServerCall, i0 syncbase.Id, i1 syncbase.Id, i2 string, i3 syncbase.SyncgroupMemberInfo) (Syncgroup, string, GenVector, error) {
	return s.impl.JoinSyncgroupAtAdmin(ctx, call, i0, i1, i2, i3)
}

func (s implSyncServerStub) HaveBlob(ctx *context.T, call rpc.ServerCall, i0 syncbase.BlobRef) (int64, Signpost, error) {
	return s.impl.HaveBlob(ctx, call, i0)
}

func (s implSyncServerStub) FetchBlob(ctx *context.T, call *SyncFetchBlobServerCallStub, i0 syncbase.BlobRef, i1 SgPriorities) (BlobSharesBySyncgroup, error) {
	return s.impl.FetchBlob(ctx, call, i0, i1)
}

func (s implSyncServerStub) FetchBlobRecipe(ctx *context.T, call *SyncFetchBlobRecipeServerCallStub, i0 syncbase.BlobRef, i1 string, i2 SgPriorities) (BlobSharesBySyncgroup, error) {
	return s.impl.FetchBlobRecipe(ctx, call, i0, i1, i2)
}

func (s implSyncServerStub) FetchChunks(ctx *context.T, call *SyncFetchChunksServerCallStub) error {
	return s.impl.FetchChunks(ctx, call)
}

func (s implSyncServerStub) RequestTakeBlob(ctx *context.T, call rpc.ServerCall, i0 syncbase.BlobRef, i1 string, i2 BlobSharesBySyncgroup) error {
	return s.impl.RequestTakeBlob(ctx, call, i0, i1, i2)
}

func (s implSyncServerStub) AcceptedBlobOwnership(ctx *context.T, call rpc.ServerCall, i0 syncbase.BlobRef, i1 string, i2 BlobSharesBySyncgroup) (string, bool, error) {
	return s.impl.AcceptedBlobOwnership(ctx, call, i0, i1, i2)
}

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

func (s implSyncServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{SyncDesc}
}

// SyncDesc describes the Sync interface.
var SyncDesc rpc.InterfaceDesc = descSync

// descSync hides the desc to keep godoc clean.
var descSync = rpc.InterfaceDesc{
	Name:    "Sync",
	PkgPath: "v.io/x/ref/services/syncbase/server/interfaces",
	Doc:     "// Sync defines methods for data exchange between Syncbases.\n// TODO(hpucha): Flesh this out further.",
	Methods: []rpc.MethodDesc{
		{
			Name: "GetTime",
			Doc:  "// GetTime returns metadata related to the Syncbase virtual clock, including\n// system clock values, last NTP timestamp, num reboots, etc.",
			InArgs: []rpc.ArgDesc{
				{"req", ``},       // TimeReq
				{"initiator", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // TimeResp
			},
		},
		{
			Name: "GetDeltas",
			Doc:  "// GetDeltas returns the responder's current generation vectors and all\n// the missing log records when compared to the initiator's generation\n// vectors for one Database for either syncgroup metadata or data.\n// The final result (in DeltaFinalResp) currently includes the\n// syncgroup priorities for blob ownership for the server.",
			InArgs: []rpc.ArgDesc{
				{"req", ``},       // DeltaReq
				{"initiator", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // DeltaFinalResp
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "PublishSyncgroup",
			Doc:  "// PublishSyncgroup is invoked on the syncgroup name (typically served\n// by a \"central\" peer) to publish the syncgroup.  It takes the name of\n// Syncbase doing the publishing (the publisher) and returns the name\n// of the Syncbase where the syncgroup is published (the publishee).\n// This allows the publisher and the publishee to learn of each other.\n// When a syncgroup is published, the publishee is given the syncgroup\n// metadata, its current version at the publisher, and the current\n// syncgroup generation vector.  The generation vector serves as a\n// checkpoint at the time of publishing.  The publishing proceeds\n// asynchronously, and the publishee learns the syncgroup history\n// through the routine p2p sync process and determines when it has\n// caught up to the level of knowledge at the time of publishing using\n// the checkpointed generation vector.  Until that point, the publishee\n// locally deems the syncgroup to be in a pending state and does not\n// mutate it.  Thus it locally rejects syncgroup joins or updates to\n// its spec until it is caught up on the syncgroup history.",
			InArgs: []rpc.ArgDesc{
				{"publisher", ``}, // string
				{"sg", ``},        // Syncgroup
				{"version", ``},   // string
				{"genvec", ``},    // GenVector
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "JoinSyncgroupAtAdmin",
			Doc:  "// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's\n// Syncbase on a syncgroup admin. It checks whether the requestor is\n// allowed to join the named syncgroup, and if so, adds the requestor to\n// the syncgroup.  It returns a copy of the updated syncgroup metadata,\n// its version, and the syncgroup generation vector at the time of the\n// join.  Similar to the PublishSyncgroup scenario, the joiner at that\n// point does not have the syncgroup history and locally deems it to be\n// in a pending state and does not mutate it.  This means it rejects\n// local updates to the syncgroup spec or, if it were also an admin on\n// the syncgroup, it would reject syncgroup joins until it is caught up\n// on the syncgroup history through p2p sync.",
			InArgs: []rpc.ArgDesc{
				{"dbId", ``},       // syncbase.Id
				{"sgId", ``},       // syncbase.Id
				{"joinerName", ``}, // string
				{"myInfo", ``},     // syncbase.SyncgroupMemberInfo
			},
			OutArgs: []rpc.ArgDesc{
				{"sg", ``},      // Syncgroup
				{"version", ``}, // string
				{"genvec", ``},  // GenVector
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "HaveBlob",
			Doc:  "// HaveBlob verifies that the peer has the requested blob, and if\n// present, returns its size.  Otherwise, it returns -1, and the location\n// hints (the Signpost) that the peer has for the blob, filtered to\n// include only data the caller is permitted to see:\n// + Device D reveals a syncgroup SG to the caller C iff\n//   - D is in SG, and\n//   - SG is in the Signpost, and\n//   - at least one of:\n//     - SG is not private, or\n//     - C has permission to join SG.\n// + Device D reveals a location hint L to caller C iff\n//   there is a syncgroup SG such that\n//   - D is in SG, and\n//   - SG is in the Signpost, and\n//   - L is in SG, and\n//   - at least one of:\n//     - SG is not private, or\n//     - C has permission to join SG, or\n//     - L is a blob server in SG.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // syncbase.BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"size", ``},     // int64
				{"signpost", ``}, // Signpost
			},
		},
		{
			Name: "FetchBlob",
			Doc:  "// FetchBlob fetches the requested blob.\n// It returns a number of blob ownership shares that the server hopes\n// the client will accept using the AcceptedBlobOwnership() call.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},             // syncbase.BlobRef
				{"mySgPriorities", ``}, // SgPriorities
			},
			OutArgs: []rpc.ArgDesc{
				{"shares", ``}, // BlobSharesBySyncgroup
			},
		},
		{
			Name: "FetchBlobRecipe",
			Doc:  "// Methods for incremental blob transfer. The transfer starts with the\n// receiver making a FetchBlobRecipe call to the sender for a given\n// BlobRef. The sender, in turn, sends the chunk hashes of all the\n// chunks that make up the requested blob (blob recipe). The receiver\n// looks up the chunk hashes in its local blob store, and identifies the\n// missing ones. The receiver then fetches the missing chunks using a\n// FetchChunks call from the sender. Finally, the receiver finishes the\n// blob fetch by combining the chunks obtained over the network with the\n// already available local chunks as per the blob recipe.\n// callerName is the syncbase Id of the caller, expressed as a string.\n// FetchBlobRecipe returns a number of blob ownership shares that the\n// server hopes the client will accept for each syncgroup using the\n// AcceptedBlobOwnership() call.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},             // syncbase.BlobRef
				{"callerName", ``},     // string
				{"mySgPriorities", ``}, // SgPriorities
			},
			OutArgs: []rpc.ArgDesc{
				{"shares", ``}, // BlobSharesBySyncgroup
			},
		},
		{
			Name: "FetchChunks",
		},
		{
			Name: "RequestTakeBlob",
			Doc:  "// RequestTakeBlob indicates that the caller wishes the server to take\n// some blob ownership shares for various syncgroups for the specified blob.\n// If the server chooses to act on the request, it may call FetchBlob/FetchBlobRecipe,\n// and ultimately AcceptedBlobOwnership().\n// callerName is the syncbase Id of the caller, expressed as a string.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},         // syncbase.BlobRef
				{"callerName", ``}, // string
				{"shares", ``},     // BlobSharesBySyncgroup
			},
		},
		{
			Name: "AcceptedBlobOwnership",
			Doc:  "// AcceptedBlobOwnership tells the server that the client callerName (a\n// syncbase Id expressed as a string) has accepted blob ownership of a\n// specified number of shares for blob br.  The server may decrement\n// its share count by up to this number.  It is safe for the server to\n// decrement its share count by fewer than the number of shares another\n// device has taken responsibility for, but unsafe to decrement it by\n// more than that that number.  It returns a hint as to whether the\n// server is likely to keep the blob itself, plus its syncbase Id\n// expressed as a string.",
			InArgs: []rpc.ArgDesc{
				{"br", ``},         // syncbase.BlobRef
				{"callerName", ``}, // string
				{"shares", ``},     // BlobSharesBySyncgroup
			},
			OutArgs: []rpc.ArgDesc{
				{"serverName", ``},  // string
				{"keepingBlob", ``}, // bool
			},
		},
	},
}

// SyncGetDeltasServerStream is the server stream for Sync.GetDeltas.
type SyncGetDeltasServerStream interface {
	// SendStream returns the send side of the Sync.GetDeltas 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 DeltaResp) error
	}
}

// SyncGetDeltasServerCall represents the context passed to Sync.GetDeltas.
type SyncGetDeltasServerCall interface {
	rpc.ServerCall
	SyncGetDeltasServerStream
}

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

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

// SendStream returns the send side of the Sync.GetDeltas server stream.
func (s *SyncGetDeltasServerCallStub) SendStream() interface {
	Send(item DeltaResp) error
} {
	return implSyncGetDeltasServerCallSend{s}
}

type implSyncGetDeltasServerCallSend struct {
	s *SyncGetDeltasServerCallStub
}

func (s implSyncGetDeltasServerCallSend) Send(item DeltaResp) error {
	return s.s.Send(item)
}

// SyncFetchBlobServerStream is the server stream for Sync.FetchBlob.
type SyncFetchBlobServerStream interface {
	// SendStream returns the send side of the Sync.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 []byte) error
	}
}

// SyncFetchBlobServerCall represents the context passed to Sync.FetchBlob.
type SyncFetchBlobServerCall interface {
	rpc.ServerCall
	SyncFetchBlobServerStream
}

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

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

// SendStream returns the send side of the Sync.FetchBlob server stream.
func (s *SyncFetchBlobServerCallStub) SendStream() interface {
	Send(item []byte) error
} {
	return implSyncFetchBlobServerCallSend{s}
}

type implSyncFetchBlobServerCallSend struct {
	s *SyncFetchBlobServerCallStub
}

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

// SyncFetchBlobRecipeServerStream is the server stream for Sync.FetchBlobRecipe.
type SyncFetchBlobRecipeServerStream interface {
	// SendStream returns the send side of the Sync.FetchBlobRecipe 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 ChunkHash) error
	}
}

// SyncFetchBlobRecipeServerCall represents the context passed to Sync.FetchBlobRecipe.
type SyncFetchBlobRecipeServerCall interface {
	rpc.ServerCall
	SyncFetchBlobRecipeServerStream
}

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

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

// SendStream returns the send side of the Sync.FetchBlobRecipe server stream.
func (s *SyncFetchBlobRecipeServerCallStub) SendStream() interface {
	Send(item ChunkHash) error
} {
	return implSyncFetchBlobRecipeServerCallSend{s}
}

type implSyncFetchBlobRecipeServerCallSend struct {
	s *SyncFetchBlobRecipeServerCallStub
}

func (s implSyncFetchBlobRecipeServerCallSend) Send(item ChunkHash) error {
	return s.s.Send(item)
}

// SyncFetchChunksServerStream is the server stream for Sync.FetchChunks.
type SyncFetchChunksServerStream interface {
	// RecvStream returns the receiver side of the Sync.FetchChunks 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() ChunkHash
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Sync.FetchChunks 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 ChunkData) error
	}
}

// SyncFetchChunksServerCall represents the context passed to Sync.FetchChunks.
type SyncFetchChunksServerCall interface {
	rpc.ServerCall
	SyncFetchChunksServerStream
}

// SyncFetchChunksServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements SyncFetchChunksServerCall.
type SyncFetchChunksServerCallStub struct {
	rpc.StreamServerCall
	valRecv ChunkHash
	errRecv error
}

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

// RecvStream returns the receiver side of the Sync.FetchChunks server stream.
func (s *SyncFetchChunksServerCallStub) RecvStream() interface {
	Advance() bool
	Value() ChunkHash
	Err() error
} {
	return implSyncFetchChunksServerCallRecv{s}
}

type implSyncFetchChunksServerCallRecv struct {
	s *SyncFetchChunksServerCallStub
}

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

// SendStream returns the send side of the Sync.FetchChunks server stream.
func (s *SyncFetchChunksServerCallStub) SendStream() interface {
	Send(item ChunkData) error
} {
	return implSyncFetchChunksServerCallSend{s}
}

type implSyncFetchChunksServerCallSend struct {
	s *SyncFetchChunksServerCallStub
}

func (s implSyncFetchChunksServerCallSend) Send(item ChunkData) error {
	return s.s.Send(item)
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_map_1     *vdl.Type
	__VDLType_map_2     *vdl.Type
	__VDLType_struct_3  *vdl.Type
	__VDLType_list_4    *vdl.Type
	__VDLType_struct_5  *vdl.Type
	__VDLType_struct_6  *vdl.Type
	__VDLType_string_7  *vdl.Type
	__VDLType_enum_8    *vdl.Type
	__VDLType_struct_9  *vdl.Type
	__VDLType_struct_10 *vdl.Type
	__VDLType_struct_11 *vdl.Type
	__VDLType_struct_12 *vdl.Type
	__VDLType_struct_13 *vdl.Type
	__VDLType_map_14    *vdl.Type
	__VDLType_map_15    *vdl.Type
	__VDLType_struct_16 *vdl.Type
	__VDLType_struct_17 *vdl.Type
	__VDLType_struct_18 *vdl.Type
	__VDLType_set_19    *vdl.Type
	__VDLType_union_20  *vdl.Type
	__VDLType_union_21  *vdl.Type
	__VDLType_struct_22 *vdl.Type
	__VDLType_map_23    *vdl.Type
	__VDLType_struct_24 *vdl.Type
	__VDLType_struct_25 *vdl.Type
	__VDLType_list_26   *vdl.Type
	__VDLType_struct_27 *vdl.Type
	__VDLType_struct_28 *vdl.Type
	__VDLType_struct_29 *vdl.Type
	__VDLType_map_30    *vdl.Type
	__VDLType_struct_31 *vdl.Type
	__VDLType_map_32    *vdl.Type
	__VDLType_struct_33 *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((*GenVector)(nil))
	vdl.Register((*Knowledge)(nil))
	vdl.Register((*LogRecMetadata)(nil))
	vdl.Register((*LogRec)(nil))
	vdl.Register((*GroupId)(nil))
	vdl.Register((*SyncgroupStatus)(nil))
	vdl.Register((*SyncgroupMemberState)(nil))
	vdl.Register((*Syncgroup)(nil))
	vdl.Register((*CollectionPerms)(nil))
	vdl.Register((*SgDeltaReq)(nil))
	vdl.Register((*DataDeltaReq)(nil))
	vdl.Register((*DeltaReq)(nil))
	vdl.Register((*DeltaResp)(nil))
	vdl.Register((*SgPriority)(nil))
	vdl.Register((*SgPriorities)(nil))
	vdl.Register((*DeltaFinalResp)(nil))
	vdl.Register((*ChunkHash)(nil))
	vdl.Register((*ChunkData)(nil))
	vdl.Register((*TimeReq)(nil))
	vdl.Register((*TimeResp)(nil))
	vdl.Register((*BlobSharesBySyncgroup)(nil))
	vdl.Register((*LocationData)(nil))
	vdl.Register((*PeerToLocationDataMap)(nil))
	vdl.Register((*Signpost)(nil))

	// Initialize type definitions.
	__VDLType_map_1 = vdl.TypeOf((*GenVector)(nil))
	__VDLType_map_2 = vdl.TypeOf((*Knowledge)(nil))
	__VDLType_struct_3 = vdl.TypeOf((*LogRecMetadata)(nil)).Elem()
	__VDLType_list_4 = vdl.TypeOf((*[]string)(nil))
	__VDLType_struct_5 = vdl.TypeOf((*vdltime.Time)(nil)).Elem()
	__VDLType_struct_6 = vdl.TypeOf((*LogRec)(nil)).Elem()
	__VDLType_string_7 = vdl.TypeOf((*GroupId)(nil))
	__VDLType_enum_8 = vdl.TypeOf((*SyncgroupStatus)(nil))
	__VDLType_struct_9 = vdl.TypeOf((*SyncgroupMemberState)(nil)).Elem()
	__VDLType_struct_10 = vdl.TypeOf((*syncbase.SyncgroupMemberInfo)(nil)).Elem()
	__VDLType_struct_11 = vdl.TypeOf((*Syncgroup)(nil)).Elem()
	__VDLType_struct_12 = vdl.TypeOf((*syncbase.Id)(nil)).Elem()
	__VDLType_struct_13 = vdl.TypeOf((*syncbase.SyncgroupSpec)(nil)).Elem()
	__VDLType_map_14 = vdl.TypeOf((*map[string]SyncgroupMemberState)(nil))
	__VDLType_map_15 = vdl.TypeOf((*CollectionPerms)(nil))
	__VDLType_struct_16 = vdl.TypeOf((*access.AccessList)(nil)).Elem()
	__VDLType_struct_17 = vdl.TypeOf((*SgDeltaReq)(nil)).Elem()
	__VDLType_struct_18 = vdl.TypeOf((*DataDeltaReq)(nil)).Elem()
	__VDLType_set_19 = vdl.TypeOf((*map[GroupId]struct{})(nil))
	__VDLType_union_20 = vdl.TypeOf((*DeltaReq)(nil))
	__VDLType_union_21 = vdl.TypeOf((*DeltaResp)(nil))
	__VDLType_struct_22 = vdl.TypeOf((*SgPriority)(nil)).Elem()
	__VDLType_map_23 = vdl.TypeOf((*SgPriorities)(nil))
	__VDLType_struct_24 = vdl.TypeOf((*DeltaFinalResp)(nil)).Elem()
	__VDLType_struct_25 = vdl.TypeOf((*ChunkHash)(nil)).Elem()
	__VDLType_list_26 = vdl.TypeOf((*[]byte)(nil))
	__VDLType_struct_27 = vdl.TypeOf((*ChunkData)(nil)).Elem()
	__VDLType_struct_28 = vdl.TypeOf((*TimeReq)(nil)).Elem()
	__VDLType_struct_29 = vdl.TypeOf((*TimeResp)(nil)).Elem()
	__VDLType_map_30 = vdl.TypeOf((*BlobSharesBySyncgroup)(nil))
	__VDLType_struct_31 = vdl.TypeOf((*LocationData)(nil)).Elem()
	__VDLType_map_32 = vdl.TypeOf((*PeerToLocationDataMap)(nil))
	__VDLType_struct_33 = vdl.TypeOf((*Signpost)(nil)).Elem()

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrDupSyncgroupPublish.ID), "{1:}{2:} duplicate publish on syncgroup: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrConnFail.ID), "{1:}{2:} connection to peer failed{:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBrokenCrConnection.ID), "{1:}{2:} CrConnection stream to client does not exist or is broken")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrDbOffline.ID), "{1:}{2:} database {3} is offline and cannot be synced{:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrGetTimeFailed.ID), "{1:}{2:} GetTime failed{:_}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNotAdmin.ID), "{1:}{2:} not an admin of the syncgroup")

	return struct{}{}
}
