// 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.
// Source: sync.vdl

package interfaces

import (
	// VDL system imports
	"io"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/vdl"
	"v.io/v23/verror"

	// VDL user imports
	"v.io/v23/security/access"
	"v.io/v23/services/syncbase/nosql"
)

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 application does not exist or is broken.")
)

func init() {
	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 application does not exist or is broken.")
}

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

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

// 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 syncbase clock like syncbase clock
	// timestamps, last NTP timestamp, num reboots, etc.
	GetTime(ctx *context.T, req TimeReq, initiator string, opts ...rpc.CallOpt) (TimeResp, error)
	// GetDeltas returns the responder's current generation vector and all
	// the missing log records when compared to the initiator's generation
	// vector for one Database for either syncgroup metadata or data.
	GetDeltas(ctx *context.T, req DeltaReq, initiator string, opts ...rpc.CallOpt) (SyncGetDeltasClientCall, error)
	// PublishSyncgroup is invoked on the syncgroup name (typically served
	// by a "central" peer) to publish the syncgroup.  It takes the name of
	// Syncbase doing the publishing (the publisher) and returns the name
	// of the Syncbase where the syncgroup is published (the publishee).
	// This allows the publisher and the publishee to learn of each other.
	// When a syncgroup is published, the publishee is given the syncgroup
	// metadata, its current version at the publisher, and the current
	// syncgroup generation vector.  The generation vector serves as a
	// checkpoint at the time of publishing.  The publishing proceeds
	// asynchronously, and the publishee learns the syncgroup history
	// through the routine p2p sync process and determines when it has
	// caught up to the level of knowledge at the time of publishing using
	// the checkpointed generation vector.  Until that point, the publishee
	// locally deems the syncgroup to be in a pending state and does not
	// mutate it.  Thus it locally rejects syncgroup joins or updates to
	// its spec until it is caught up on the syncgroup history.
	PublishSyncgroup(ctx *context.T, publisher string, sg Syncgroup, version string, genvec PrefixGenVector, opts ...rpc.CallOpt) (string, error)
	// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's
	// Syncbase on a syncgroup admin. It checks whether the requestor is
	// allowed to join the named syncgroup, and if so, adds the requestor to
	// the syncgroup.  It returns a copy of the updated syncgroup metadata,
	// its version, and the syncgroup generation vector at the time of the
	// join.  Similar to the PublishSyncgroup scenario, the joiner at that
	// point does not have the syncgroup history and locally deems it to be
	// in a pending state and does not mutate it.  This means it rejects
	// local updates to the syncgroup spec or, if it were also an admin on
	// the syncgroup, it would reject syncgroup joins until it is caught up
	// on the syncgroup history through p2p sync.
	JoinSyncgroupAtAdmin(ctx *context.T, sgName string, joinerName string, myInfo nosql.SyncgroupMemberInfo, opts ...rpc.CallOpt) (sg Syncgroup, version string, genvec PrefixGenVector, err error)
	// HaveBlob verifies that the peer has the requested blob, and if
	// present, returns its size.
	HaveBlob(ctx *context.T, br nosql.BlobRef, opts ...rpc.CallOpt) (int64, error)
	// FetchBlob fetches the requested blob.
	FetchBlob(ctx *context.T, br nosql.BlobRef, opts ...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.
	FetchBlobRecipe(ctx *context.T, br nosql.BlobRef, opts ...rpc.CallOpt) (SyncFetchBlobRecipeClientCall, error)
	FetchChunks(*context.T, ...rpc.CallOpt) (SyncFetchChunksClientCall, 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 PrefixGenVector, 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 string, i1 string, i2 nosql.SyncgroupMemberInfo, opts ...rpc.CallOpt) (o0 Syncgroup, o1 string, o2 PrefixGenVector, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "JoinSyncgroupAtAdmin", []interface{}{i0, i1, i2}, []interface{}{&o0, &o1, &o2}, opts...)
	return
}

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

func (c implSyncClientStub) FetchBlob(ctx *context.T, i0 nosql.BlobRef, opts ...rpc.CallOpt) (ocall SyncFetchBlobClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "FetchBlob", []interface{}{i0}, opts...); err != nil {
		return
	}
	ocall = &implSyncFetchBlobClientCall{ClientCall: call}
	return
}

func (c implSyncClientStub) FetchBlobRecipe(ctx *context.T, i0 nosql.BlobRef, opts ...rpc.CallOpt) (ocall SyncFetchBlobRecipeClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "FetchBlobRecipe", []interface{}{i0}, 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
}

// 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() 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() (err error) {
	err = c.ClientCall.Finish()
	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() 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() (err error) {
	err = c.ClientCall.Finish()
	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() 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() (err error) {
	err = c.ClientCall.Finish()
	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 syncbase clock like syncbase clock
	// timestamps, last NTP timestamp, num reboots, etc.
	GetTime(ctx *context.T, call rpc.ServerCall, req TimeReq, initiator string) (TimeResp, error)
	// GetDeltas returns the responder's current generation vector and all
	// the missing log records when compared to the initiator's generation
	// vector for one Database for either syncgroup metadata or data.
	GetDeltas(ctx *context.T, call SyncGetDeltasServerCall, req DeltaReq, initiator string) error
	// PublishSyncgroup is invoked on the syncgroup name (typically served
	// by a "central" peer) to publish the syncgroup.  It takes the name of
	// Syncbase doing the publishing (the publisher) and returns the name
	// of the Syncbase where the syncgroup is published (the publishee).
	// This allows the publisher and the publishee to learn of each other.
	// When a syncgroup is published, the publishee is given the syncgroup
	// metadata, its current version at the publisher, and the current
	// syncgroup generation vector.  The generation vector serves as a
	// checkpoint at the time of publishing.  The publishing proceeds
	// asynchronously, and the publishee learns the syncgroup history
	// through the routine p2p sync process and determines when it has
	// caught up to the level of knowledge at the time of publishing using
	// the checkpointed generation vector.  Until that point, the publishee
	// locally deems the syncgroup to be in a pending state and does not
	// mutate it.  Thus it locally rejects syncgroup joins or updates to
	// its spec until it is caught up on the syncgroup history.
	PublishSyncgroup(ctx *context.T, call rpc.ServerCall, publisher string, sg Syncgroup, version string, genvec PrefixGenVector) (string, error)
	// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's
	// Syncbase on a syncgroup admin. It checks whether the requestor is
	// allowed to join the named syncgroup, and if so, adds the requestor to
	// the syncgroup.  It returns a copy of the updated syncgroup metadata,
	// its version, and the syncgroup generation vector at the time of the
	// join.  Similar to the PublishSyncgroup scenario, the joiner at that
	// point does not have the syncgroup history and locally deems it to be
	// in a pending state and does not mutate it.  This means it rejects
	// local updates to the syncgroup spec or, if it were also an admin on
	// the syncgroup, it would reject syncgroup joins until it is caught up
	// on the syncgroup history through p2p sync.
	JoinSyncgroupAtAdmin(ctx *context.T, call rpc.ServerCall, sgName string, joinerName string, myInfo nosql.SyncgroupMemberInfo) (sg Syncgroup, version string, genvec PrefixGenVector, err error)
	// HaveBlob verifies that the peer has the requested blob, and if
	// present, returns its size.
	HaveBlob(ctx *context.T, call rpc.ServerCall, br nosql.BlobRef) (int64, error)
	// FetchBlob fetches the requested blob.
	FetchBlob(ctx *context.T, call SyncFetchBlobServerCall, br nosql.BlobRef) 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.
	FetchBlobRecipe(ctx *context.T, call SyncFetchBlobRecipeServerCall, br nosql.BlobRef) error
	FetchChunks(*context.T, SyncFetchChunksServerCall) 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 syncbase clock like syncbase clock
	// timestamps, last NTP timestamp, num reboots, etc.
	GetTime(ctx *context.T, call rpc.ServerCall, req TimeReq, initiator string) (TimeResp, error)
	// GetDeltas returns the responder's current generation vector and all
	// the missing log records when compared to the initiator's generation
	// vector for one Database for either syncgroup metadata or data.
	GetDeltas(ctx *context.T, call *SyncGetDeltasServerCallStub, req DeltaReq, initiator string) error
	// PublishSyncgroup is invoked on the syncgroup name (typically served
	// by a "central" peer) to publish the syncgroup.  It takes the name of
	// Syncbase doing the publishing (the publisher) and returns the name
	// of the Syncbase where the syncgroup is published (the publishee).
	// This allows the publisher and the publishee to learn of each other.
	// When a syncgroup is published, the publishee is given the syncgroup
	// metadata, its current version at the publisher, and the current
	// syncgroup generation vector.  The generation vector serves as a
	// checkpoint at the time of publishing.  The publishing proceeds
	// asynchronously, and the publishee learns the syncgroup history
	// through the routine p2p sync process and determines when it has
	// caught up to the level of knowledge at the time of publishing using
	// the checkpointed generation vector.  Until that point, the publishee
	// locally deems the syncgroup to be in a pending state and does not
	// mutate it.  Thus it locally rejects syncgroup joins or updates to
	// its spec until it is caught up on the syncgroup history.
	PublishSyncgroup(ctx *context.T, call rpc.ServerCall, publisher string, sg Syncgroup, version string, genvec PrefixGenVector) (string, error)
	// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's
	// Syncbase on a syncgroup admin. It checks whether the requestor is
	// allowed to join the named syncgroup, and if so, adds the requestor to
	// the syncgroup.  It returns a copy of the updated syncgroup metadata,
	// its version, and the syncgroup generation vector at the time of the
	// join.  Similar to the PublishSyncgroup scenario, the joiner at that
	// point does not have the syncgroup history and locally deems it to be
	// in a pending state and does not mutate it.  This means it rejects
	// local updates to the syncgroup spec or, if it were also an admin on
	// the syncgroup, it would reject syncgroup joins until it is caught up
	// on the syncgroup history through p2p sync.
	JoinSyncgroupAtAdmin(ctx *context.T, call rpc.ServerCall, sgName string, joinerName string, myInfo nosql.SyncgroupMemberInfo) (sg Syncgroup, version string, genvec PrefixGenVector, err error)
	// HaveBlob verifies that the peer has the requested blob, and if
	// present, returns its size.
	HaveBlob(ctx *context.T, call rpc.ServerCall, br nosql.BlobRef) (int64, error)
	// FetchBlob fetches the requested blob.
	FetchBlob(ctx *context.T, call *SyncFetchBlobServerCallStub, br nosql.BlobRef) 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.
	FetchBlobRecipe(ctx *context.T, call *SyncFetchBlobRecipeServerCallStub, br nosql.BlobRef) error
	FetchChunks(*context.T, *SyncFetchChunksServerCallStub) 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) 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 PrefixGenVector) (string, error) {
	return s.impl.PublishSyncgroup(ctx, call, i0, i1, i2, i3)
}

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

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

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

func (s implSyncServerStub) FetchBlobRecipe(ctx *context.T, call *SyncFetchBlobRecipeServerCallStub, i0 nosql.BlobRef) error {
	return s.impl.FetchBlobRecipe(ctx, call, i0)
}

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

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 syncbase clock like syncbase clock\n// timestamps, last NTP timestamp, num reboots, etc.",
			InArgs: []rpc.ArgDesc{
				{"req", ``},       // TimeReq
				{"initiator", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // TimeResp
			},
		},
		{
			Name: "GetDeltas",
			Doc:  "// GetDeltas returns the responder's current generation vector and all\n// the missing log records when compared to the initiator's generation\n// vector for one Database for either syncgroup metadata or data.",
			InArgs: []rpc.ArgDesc{
				{"req", ``},       // DeltaReq
				{"initiator", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "PublishSyncgroup",
			Doc:  "// PublishSyncgroup is invoked on the syncgroup name (typically served\n// by a \"central\" peer) to publish the syncgroup.  It takes the name of\n// Syncbase doing the publishing (the publisher) and returns the name\n// of the Syncbase where the syncgroup is published (the publishee).\n// This allows the publisher and the publishee to learn of each other.\n// When a syncgroup is published, the publishee is given the syncgroup\n// metadata, its current version at the publisher, and the current\n// syncgroup generation vector.  The generation vector serves as a\n// checkpoint at the time of publishing.  The publishing proceeds\n// asynchronously, and the publishee learns the syncgroup history\n// through the routine p2p sync process and determines when it has\n// caught up to the level of knowledge at the time of publishing using\n// the checkpointed generation vector.  Until that point, the publishee\n// locally deems the syncgroup to be in a pending state and does not\n// mutate it.  Thus it locally rejects syncgroup joins or updates to\n// its spec until it is caught up on the syncgroup history.",
			InArgs: []rpc.ArgDesc{
				{"publisher", ``}, // string
				{"sg", ``},        // Syncgroup
				{"version", ``},   // string
				{"genvec", ``},    // PrefixGenVector
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "JoinSyncgroupAtAdmin",
			Doc:  "// JoinSyncgroupAtAdmin is invoked by a prospective syncgroup member's\n// Syncbase on a syncgroup admin. It checks whether the requestor is\n// allowed to join the named syncgroup, and if so, adds the requestor to\n// the syncgroup.  It returns a copy of the updated syncgroup metadata,\n// its version, and the syncgroup generation vector at the time of the\n// join.  Similar to the PublishSyncgroup scenario, the joiner at that\n// point does not have the syncgroup history and locally deems it to be\n// in a pending state and does not mutate it.  This means it rejects\n// local updates to the syncgroup spec or, if it were also an admin on\n// the syncgroup, it would reject syncgroup joins until it is caught up\n// on the syncgroup history through p2p sync.",
			InArgs: []rpc.ArgDesc{
				{"sgName", ``},     // string
				{"joinerName", ``}, // string
				{"myInfo", ``},     // nosql.SyncgroupMemberInfo
			},
			OutArgs: []rpc.ArgDesc{
				{"sg", ``},      // Syncgroup
				{"version", ``}, // string
				{"genvec", ``},  // PrefixGenVector
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "HaveBlob",
			Doc:  "// HaveBlob verifies that the peer has the requested blob, and if\n// present, returns its size.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // nosql.BlobRef
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // int64
			},
		},
		{
			Name: "FetchBlob",
			Doc:  "// FetchBlob fetches the requested blob.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // nosql.BlobRef
			},
		},
		{
			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.",
			InArgs: []rpc.ArgDesc{
				{"br", ``}, // nosql.BlobRef
			},
		},
		{
			Name: "FetchChunks",
		},
	},
}

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