// 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.
	//
	// Requires: Always allowed.
	// TODO(ivanpi): Consider adding an ACL or checking syncgroup ACLs.
	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.
	//
	// Requires: Read on syncgroup.
	// TODO(ivanpi): Consider rechecking Collection Read access.
	// The caller should verify that all received changes (data, ACLs, spec) are
	// signed by a blessing that had the appropriate permission (Write or Admin).
	// TODO(ivanpi): Implement signatures and signature verification.
	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.
	//
	// Requires: Always allowed.
	// TODO(ivanpi): Add separate ACL for PublishSyncgroup and check it.
	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.
	//
	// Requires: Read on syncgroup and on all Collections in the syncgroup spec.
	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)
	// RequestTakeBlobs indicates that the caller wishes the server to take
	// some blob ownership shares for various syncgroups for the specified blobs.
	// 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.
	RequestTakeBlobs(_ *context.T, callerName string, blobRefToShares map[syncbase.BlobRef]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)
	// GetBlobShares returns the number of ownership shares for the specified blob
	// held by the server.  It is used by the DevModeGetBlobShares() call in the
	// service.  It uses the "map[string]int32" type, rather than
	// interfaces.BlobSharesBySyncgroup, so that the client of this call code doesn't
	// need to reach into the sync service's type definitions.
	GetBlobShares(_ *context.T, br syncbase.BlobRef, _ ...rpc.CallOpt) (map[string]int32, 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) RequestTakeBlobs(ctx *context.T, i0 string, i1 map[syncbase.BlobRef]BlobSharesBySyncgroup, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "RequestTakeBlobs", []interface{}{i0, i1}, 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
}

func (c implSyncClientStub) GetBlobShares(ctx *context.T, i0 syncbase.BlobRef, opts ...rpc.CallOpt) (o0 map[string]int32, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetBlobShares", []interface{}{i0}, []interface{}{&o0}, 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.
	//
	// Requires: Always allowed.
	// TODO(ivanpi): Consider adding an ACL or checking syncgroup ACLs.
	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.
	//
	// Requires: Read on syncgroup.
	// TODO(ivanpi): Consider rechecking Collection Read access.
	// The caller should verify that all received changes (data, ACLs, spec) are
	// signed by a blessing that had the appropriate permission (Write or Admin).
	// TODO(ivanpi): Implement signatures and signature verification.
	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.
	//
	// Requires: Always allowed.
	// TODO(ivanpi): Add separate ACL for PublishSyncgroup and check it.
	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.
	//
	// Requires: Read on syncgroup and on all Collections in the syncgroup spec.
	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
	// RequestTakeBlobs indicates that the caller wishes the server to take
	// some blob ownership shares for various syncgroups for the specified blobs.
	// 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.
	RequestTakeBlobs(_ *context.T, _ rpc.ServerCall, callerName string, blobRefToShares map[syncbase.BlobRef]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)
	// GetBlobShares returns the number of ownership shares for the specified blob
	// held by the server.  It is used by the DevModeGetBlobShares() call in the
	// service.  It uses the "map[string]int32" type, rather than
	// interfaces.BlobSharesBySyncgroup, so that the client of this call code doesn't
	// need to reach into the sync service's type definitions.
	GetBlobShares(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef) (map[string]int32, 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.
	//
	// Requires: Always allowed.
	// TODO(ivanpi): Consider adding an ACL or checking syncgroup ACLs.
	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.
	//
	// Requires: Read on syncgroup.
	// TODO(ivanpi): Consider rechecking Collection Read access.
	// The caller should verify that all received changes (data, ACLs, spec) are
	// signed by a blessing that had the appropriate permission (Write or Admin).
	// TODO(ivanpi): Implement signatures and signature verification.
	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.
	//
	// Requires: Always allowed.
	// TODO(ivanpi): Add separate ACL for PublishSyncgroup and check it.
	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.
	//
	// Requires: Read on syncgroup and on all Collections in the syncgroup spec.
	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
	// RequestTakeBlobs indicates that the caller wishes the server to take
	// some blob ownership shares for various syncgroups for the specified blobs.
	// 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.
	RequestTakeBlobs(_ *context.T, _ rpc.ServerCall, callerName string, blobRefToShares map[syncbase.BlobRef]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)
	// GetBlobShares returns the number of ownership shares for the specified blob
	// held by the server.  It is used by the DevModeGetBlobShares() call in the
	// service.  It uses the "map[string]int32" type, rather than
	// interfaces.BlobSharesBySyncgroup, so that the client of this call code doesn't
	// need to reach into the sync service's type definitions.
	GetBlobShares(_ *context.T, _ rpc.ServerCall, br syncbase.BlobRef) (map[string]int32, 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) RequestTakeBlobs(ctx *context.T, call rpc.ServerCall, i0 string, i1 map[syncbase.BlobRef]BlobSharesBySyncgroup) error {
	return s.impl.RequestTakeBlobs(ctx, call, i0, i1)
}

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) GetBlobShares(ctx *context.T, call rpc.ServerCall, i0 syncbase.BlobRef) (map[string]int32, error) {
	return s.impl.GetBlobShares(ctx, call, i0)
}

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.\n//\n// Requires: Always allowed.\n// TODO(ivanpi): Consider adding an ACL or checking syncgroup ACLs.",
			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.\n//\n// Requires: Read on syncgroup.\n// TODO(ivanpi): Consider rechecking Collection Read access.\n// The caller should verify that all received changes (data, ACLs, spec) are\n// signed by a blessing that had the appropriate permission (Write or Admin).\n// TODO(ivanpi): Implement signatures and signature verification.",
			InArgs: []rpc.ArgDesc{
				{"req", ``},       // DeltaReq
				{"initiator", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // DeltaFinalResp
			},
		},
		{
			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.\n//\n// Requires: Always allowed.\n// TODO(ivanpi): Add separate ACL for PublishSyncgroup and check it.",
			InArgs: []rpc.ArgDesc{
				{"publisher", ``}, // string
				{"sg", ``},        // Syncgroup
				{"version", ``},   // string
				{"genvec", ``},    // GenVector
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
		},
		{
			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.\n//\n// Requires: Read on syncgroup and on all Collections in the syncgroup spec.",
			InArgs: []rpc.ArgDesc{
				{"dbId", ``},       // syncbase.Id
				{"sgId", ``},       // syncbase.Id
				{"joinerName", ``}, // string
				{"myInfo", ``},     // syncbase.SyncgroupMemberInfo
			},
			OutArgs: []rpc.ArgDesc{
				{"sg", ``},      // Syncgroup
				{"version", ``}, // string
				{"genvec", ``},  // GenVector
			},
		},
		{
			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: "RequestTakeBlobs",
			Doc:  "// RequestTakeBlobs indicates that the caller wishes the server to take\n// some blob ownership shares for various syncgroups for the specified blobs.\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{
				{"callerName", ``},      // string
				{"blobRefToShares", ``}, // map[syncbase.BlobRef]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
			},
		},
		{
			Name: "GetBlobShares",
			Doc:  "// GetBlobShares returns the number of ownership shares for the specified blob\n// held by the server.  It is used by the DevModeGetBlobShares() call in the\n// service.  It uses the \"map[string]int32\" type, rather than\n// interfaces.BlobSharesBySyncgroup, so that the client of this call code doesn't\n// need to reach into the sync service's type definitions.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // syncbase.BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // map[string]int32
			},
		},
	},
}

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