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

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