// Copyright 2016 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: ifc

// Package messenger defines interfaces for peer-to-peer messaging where the
// originator of the message and its recipient don't necessarily have a direct
// network connection.
//
// Messages are opportunistically relayed from device to device until they
// reach their destination.
package ifc

import (
	"io"
	"time"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/vdl"
	vdltime "v.io/v23/vdlroot/time"
	"v.io/v23/verror"
)

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

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

// Message contains the metadata of a message, not the content of the message.
// It is EXPERIMENTAL and can change at any time.
type Message struct {
	// The list of nodes that have relayed this message. Each node
	// must add its own name to the list before sending it to another
	// node, either via Push() or Pull().
	Hops []string
	// The identity of the sender. Can be used to both authenticate
	// the message and to authorize sending or relaying it.
	SenderBlessings security.Blessings
	// Any required discharges to prove the sender blessings are still
	// valid.
	SenderDischarges map[string]security.Discharge
	// Proof that the sender sent this message. The signature covers
	// all the fields below.
	Signature security.Signature
	// The unique ID of this message.
	Id string
	// The intended recipient of the message.
	// TBD: blessing pattern or email? Or something else?
	Recipient string
	// When the message was created.
	CreationTime time.Time
	// The lifespan of the message. The message can be deleted by everyone
	// when CreationTime + Lifespan has been reached.
	Lifespan time.Duration
	// The length of the message's content.
	Length int64
	// The sha256 hash of the message's content.
	Sha256 []byte
}

func (Message) __VDLReflect(struct {
	Name string `vdl:"messenger/ifc.Message"`
}) {
}

func (x Message) VDLIsZero() bool {
	if len(x.Hops) != 0 {
		return false
	}
	if !x.SenderBlessings.IsZero() {
		return false
	}
	if len(x.SenderDischarges) != 0 {
		return false
	}
	if !x.Signature.VDLIsZero() {
		return false
	}
	if x.Id != "" {
		return false
	}
	if x.Recipient != "" {
		return false
	}
	if !x.CreationTime.IsZero() {
		return false
	}
	if x.Lifespan != 0 {
		return false
	}
	if x.Length != 0 {
		return false
	}
	if len(x.Sha256) != 0 {
		return false
	}
	return true
}

func (x Message) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if len(x.Hops) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Hops); err != nil {
			return err
		}
	}
	if !x.SenderBlessings.IsZero() {
		if err := enc.NextField(1); err != nil {
			return err
		}
		var wire security.WireBlessings
		if err := security.WireBlessingsFromNative(&wire, x.SenderBlessings); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.SenderDischarges) != 0 {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_2(enc, x.SenderDischarges); err != nil {
			return err
		}
	}
	if !x.Signature.VDLIsZero() {
		if err := enc.NextField(3); err != nil {
			return err
		}
		if err := x.Signature.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Id != "" {
		if err := enc.NextFieldValueString(4, vdl.StringType, x.Id); err != nil {
			return err
		}
	}
	if x.Recipient != "" {
		if err := enc.NextFieldValueString(5, vdl.StringType, x.Recipient); err != nil {
			return err
		}
	}
	if !x.CreationTime.IsZero() {
		if err := enc.NextField(6); err != nil {
			return err
		}
		var wire vdltime.Time
		if err := vdltime.TimeFromNative(&wire, x.CreationTime); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Lifespan != 0 {
		if err := enc.NextField(7); err != nil {
			return err
		}
		var wire vdltime.Duration
		if err := vdltime.DurationFromNative(&wire, x.Lifespan); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Length != 0 {
		if err := enc.NextFieldValueInt(8, vdl.Int64Type, x.Length); err != nil {
			return err
		}
	}
	if len(x.Sha256) != 0 {
		if err := enc.NextFieldValueBytes(9, __VDLType_list_8, x.Sha256); 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_2); 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 __VDLWriteAnon_map_2(enc vdl.Encoder, x map[string]security.Discharge) error {
	if err := enc.StartValue(__VDLType_map_4); 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
		}
		var wire security.WireDischarge
		if err := security.WireDischargeFromNative(&wire, elem); err != nil {
			return err
		}
		switch {
		case wire == nil:
			// Write the zero value of the union type.
			if err := vdl.ZeroValue(__VDLType_union_9).VDLWrite(enc); err != nil {
				return err
			}
		default:
			if err := wire.VDLWrite(enc); err != nil {
				return err
			}
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Message) VDLRead(dec vdl.Decoder) error {
	*x = Message{}
	if err := dec.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_1 {
			index = __VDLType_struct_1.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := __VDLReadAnon_list_1(dec, &x.Hops); err != nil {
				return err
			}
		case 1:
			var wire security.WireBlessings
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := security.WireBlessingsToNative(wire, &x.SenderBlessings); err != nil {
				return err
			}
		case 2:
			if err := __VDLReadAnon_map_2(dec, &x.SenderDischarges); err != nil {
				return err
			}
		case 3:
			if err := x.Signature.VDLRead(dec); err != nil {
				return err
			}
		case 4:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Id = value
			}
		case 5:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Recipient = value
			}
		case 6:
			var wire vdltime.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.TimeToNative(wire, &x.CreationTime); err != nil {
				return err
			}
		case 7:
			var wire vdltime.Duration
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := vdltime.DurationToNative(wire, &x.Lifespan); err != nil {
				return err
			}
		case 8:
			switch value, err := dec.ReadValueInt(64); {
			case err != nil:
				return err
			default:
				x.Length = value
			}
		case 9:
			if err := dec.ReadValueBytes(-1, &x.Sha256); err != nil {
				return err
			}
		}
	}
}

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

func __VDLReadAnon_map_2(dec vdl.Decoder, x *map[string]security.Discharge) error {
	if err := dec.StartValue(__VDLType_map_4); err != nil {
		return err
	}
	var tmpMap map[string]security.Discharge
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[string]security.Discharge, len)
	}
	for {
		switch done, key, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		default:
			var elem security.Discharge
			var wire security.WireDischarge
			if err := security.VDLReadWireDischarge(dec, &wire); err != nil {
				return err
			}
			if err := security.WireDischargeToNative(wire, &elem); err != nil {
				return err
			}
			if tmpMap == nil {
				tmpMap = make(map[string]security.Discharge)
			}
			tmpMap[key] = elem
		}
	}
}

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

var (
	ErrAlreadySeen        = verror.Register("messenger/ifc.AlreadySeen", verror.NoRetry, "{1:}{2:} message id already seen: {3}")
	ErrBusy               = verror.Register("messenger/ifc.Busy", verror.RetryBackoff, "{1:}{2:} message is already opened")
	ErrContentMismatch    = verror.Register("messenger/ifc.ContentMismatch", verror.NoRetry, "{1:}{2:} the sha256 hash doesn't match the message content")
	ErrExpired            = verror.Register("messenger/ifc.Expired", verror.NoRetry, "{1:}{2:} message lifespan expired: {3} + {4} < {5}")
	ErrIncorrectOffset    = verror.Register("messenger/ifc.IncorrectOffset", verror.NoRetry, "{1:}{2:} the specified file offset is incorrect ({3} != {4})")
	ErrInvalidSignature   = verror.Register("messenger/ifc.InvalidSignature", verror.NoRetry, "{1:}{2:} message signature is invalid")
	ErrMessageIdCollision = verror.Register("messenger/ifc.MessageIdCollision", verror.NoRetry, "{1:}{2:} message id already seen with different content: {3}")
	ErrNoRoute            = verror.Register("messenger/ifc.NoRoute", verror.NoRetry, "{1:}{2:} no route for recipient: {3}")
	ErrRateLimitExceeded  = verror.Register("messenger/ifc.RateLimitExceeded", verror.RetryBackoff, "{1:}{2:} request rate limit exceeded: {3} req/s")
	ErrTooBig             = verror.Register("messenger/ifc.TooBig", verror.NoRetry, "{1:}{2:} message is too big, limit: {3}")
	ErrTooManyHops        = verror.Register("messenger/ifc.TooManyHops", verror.NoRetry, "{1:}{2:} too many hops, limit: {3}")
)

// NewErrAlreadySeen returns an error with the ErrAlreadySeen ID.
func NewErrAlreadySeen(ctx *context.T, Id string) error {
	return verror.New(ErrAlreadySeen, ctx, Id)
}

// NewErrBusy returns an error with the ErrBusy ID.
func NewErrBusy(ctx *context.T, Id string) error {
	return verror.New(ErrBusy, ctx, Id)
}

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

// NewErrExpired returns an error with the ErrExpired ID.
func NewErrExpired(ctx *context.T, CreationTime time.Time, Lifespan time.Duration, Now time.Time) error {
	return verror.New(ErrExpired, ctx, CreationTime, Lifespan, Now)
}

// NewErrIncorrectOffset returns an error with the ErrIncorrectOffset ID.
func NewErrIncorrectOffset(ctx *context.T, Offset int64, Size int64) error {
	return verror.New(ErrIncorrectOffset, ctx, Offset, Size)
}

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

// NewErrMessageIdCollision returns an error with the ErrMessageIdCollision ID.
func NewErrMessageIdCollision(ctx *context.T, Id string) error {
	return verror.New(ErrMessageIdCollision, ctx, Id)
}

// NewErrNoRoute returns an error with the ErrNoRoute ID.
func NewErrNoRoute(ctx *context.T, Recipient string) error {
	return verror.New(ErrNoRoute, ctx, Recipient)
}

// NewErrRateLimitExceeded returns an error with the ErrRateLimitExceeded ID.
func NewErrRateLimitExceeded(ctx *context.T, Limit float32) error {
	return verror.New(ErrRateLimitExceeded, ctx, Limit)
}

// NewErrTooBig returns an error with the ErrTooBig ID.
func NewErrTooBig(ctx *context.T, Limit int64) error {
	return verror.New(ErrTooBig, ctx, Limit)
}

// NewErrTooManyHops returns an error with the ErrTooManyHops ID.
func NewErrTooManyHops(ctx *context.T, Limit int32) error {
	return verror.New(ErrTooManyHops, ctx, Limit)
}

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

// MessengerClientMethods is the client interface
// containing Messenger methods.
//
// Messenger defines the interface to talk to nodes that can relay messages.
// This interface is EXPERIMENTAL and can change at any time.
type MessengerClientMethods interface {
	// Diff compares the set of messages on the sender with the set of
	// messages on the receiver. The sender streams batches of message IDs
	// and the receiver reponds with one bool for each message ID. A true
	// value means the receiver has the message, a false value means it
	// doesn't.
	Diff(*context.T, ...rpc.CallOpt) (MessengerDiffClientCall, error)
	// Push accepts a message. The receiver may be the final recipient
	// or a relay. If the receiver has already seen this message or
	// if it cannot relay the message, it should return a error.
	//
	// The message content is streamed to the receiver. The content is
	// opaque to everyone except the final recipient.
	Push(_ *context.T, Msg Message, Offset int64, _ ...rpc.CallOpt) (MessengerPushClientCall, error)
	// ResumeOffset returns the size of the partially transferred message.
	// The caller will use it to resume the transfer. If the message doesn't
	// exist yet, the returned offset will be 0.
	ResumeOffset(_ *context.T, Msg Message, _ ...rpc.CallOpt) (Offset int64, _ error)
}

// MessengerClientStub adds universal methods to MessengerClientMethods.
type MessengerClientStub interface {
	MessengerClientMethods
	rpc.UniversalServiceMethods
}

// MessengerClient returns a client stub for Messenger.
func MessengerClient(name string) MessengerClientStub {
	return implMessengerClientStub{name}
}

type implMessengerClientStub struct {
	name string
}

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

func (c implMessengerClientStub) Push(ctx *context.T, i0 Message, i1 int64, opts ...rpc.CallOpt) (ocall MessengerPushClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Push", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	ocall = &implMessengerPushClientCall{ClientCall: call}
	return
}

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

// MessengerDiffClientStream is the client stream for Messenger.Diff.
type MessengerDiffClientStream interface {
	// RecvStream returns the receiver side of the Messenger.Diff 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() []bool
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Messenger.Diff 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 []string) 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
	}
}

// MessengerDiffClientCall represents the call returned from Messenger.Diff.
type MessengerDiffClientCall interface {
	MessengerDiffClientStream
	// 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 implMessengerDiffClientCall struct {
	rpc.ClientCall
	valRecv []bool
	errRecv error
}

func (c *implMessengerDiffClientCall) RecvStream() interface {
	Advance() bool
	Value() []bool
	Err() error
} {
	return implMessengerDiffClientCallRecv{c}
}

type implMessengerDiffClientCallRecv struct {
	c *implMessengerDiffClientCall
}

func (c implMessengerDiffClientCallRecv) Advance() bool {
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implMessengerDiffClientCallRecv) Value() []bool {
	return c.c.valRecv
}
func (c implMessengerDiffClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implMessengerDiffClientCall) SendStream() interface {
	Send(item []string) error
	Close() error
} {
	return implMessengerDiffClientCallSend{c}
}

type implMessengerDiffClientCallSend struct {
	c *implMessengerDiffClientCall
}

func (c implMessengerDiffClientCallSend) Send(item []string) error {
	return c.c.Send(item)
}
func (c implMessengerDiffClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implMessengerDiffClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// MessengerPushClientStream is the client stream for Messenger.Push.
type MessengerPushClientStream interface {
	// SendStream returns the send side of the Messenger.Push 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 []byte) 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
	}
}

// MessengerPushClientCall represents the call returned from Messenger.Push.
type MessengerPushClientCall interface {
	MessengerPushClientStream
	// 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 implMessengerPushClientCall struct {
	rpc.ClientCall
}

func (c *implMessengerPushClientCall) SendStream() interface {
	Send(item []byte) error
	Close() error
} {
	return implMessengerPushClientCallSend{c}
}

type implMessengerPushClientCallSend struct {
	c *implMessengerPushClientCall
}

func (c implMessengerPushClientCallSend) Send(item []byte) error {
	return c.c.Send(item)
}
func (c implMessengerPushClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implMessengerPushClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// MessengerServerMethods is the interface a server writer
// implements for Messenger.
//
// Messenger defines the interface to talk to nodes that can relay messages.
// This interface is EXPERIMENTAL and can change at any time.
type MessengerServerMethods interface {
	// Diff compares the set of messages on the sender with the set of
	// messages on the receiver. The sender streams batches of message IDs
	// and the receiver reponds with one bool for each message ID. A true
	// value means the receiver has the message, a false value means it
	// doesn't.
	Diff(*context.T, MessengerDiffServerCall) error
	// Push accepts a message. The receiver may be the final recipient
	// or a relay. If the receiver has already seen this message or
	// if it cannot relay the message, it should return a error.
	//
	// The message content is streamed to the receiver. The content is
	// opaque to everyone except the final recipient.
	Push(_ *context.T, _ MessengerPushServerCall, Msg Message, Offset int64) error
	// ResumeOffset returns the size of the partially transferred message.
	// The caller will use it to resume the transfer. If the message doesn't
	// exist yet, the returned offset will be 0.
	ResumeOffset(_ *context.T, _ rpc.ServerCall, Msg Message) (Offset int64, _ error)
}

// MessengerServerStubMethods is the server interface containing
// Messenger methods, as expected by rpc.Server.
// The only difference between this interface and MessengerServerMethods
// is the streaming methods.
type MessengerServerStubMethods interface {
	// Diff compares the set of messages on the sender with the set of
	// messages on the receiver. The sender streams batches of message IDs
	// and the receiver reponds with one bool for each message ID. A true
	// value means the receiver has the message, a false value means it
	// doesn't.
	Diff(*context.T, *MessengerDiffServerCallStub) error
	// Push accepts a message. The receiver may be the final recipient
	// or a relay. If the receiver has already seen this message or
	// if it cannot relay the message, it should return a error.
	//
	// The message content is streamed to the receiver. The content is
	// opaque to everyone except the final recipient.
	Push(_ *context.T, _ *MessengerPushServerCallStub, Msg Message, Offset int64) error
	// ResumeOffset returns the size of the partially transferred message.
	// The caller will use it to resume the transfer. If the message doesn't
	// exist yet, the returned offset will be 0.
	ResumeOffset(_ *context.T, _ rpc.ServerCall, Msg Message) (Offset int64, _ error)
}

// MessengerServerStub adds universal methods to MessengerServerStubMethods.
type MessengerServerStub interface {
	MessengerServerStubMethods
	// Describe the Messenger interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implMessengerServerStub) Diff(ctx *context.T, call *MessengerDiffServerCallStub) error {
	return s.impl.Diff(ctx, call)
}

func (s implMessengerServerStub) Push(ctx *context.T, call *MessengerPushServerCallStub, i0 Message, i1 int64) error {
	return s.impl.Push(ctx, call, i0, i1)
}

func (s implMessengerServerStub) ResumeOffset(ctx *context.T, call rpc.ServerCall, i0 Message) (int64, error) {
	return s.impl.ResumeOffset(ctx, call, i0)
}

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

func (s implMessengerServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{MessengerDesc}
}

// MessengerDesc describes the Messenger interface.
var MessengerDesc rpc.InterfaceDesc = descMessenger

// descMessenger hides the desc to keep godoc clean.
var descMessenger = rpc.InterfaceDesc{
	Name:    "Messenger",
	PkgPath: "messenger/ifc",
	Doc:     "// Messenger defines the interface to talk to nodes that can relay messages.\n// This interface is EXPERIMENTAL and can change at any time.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Diff",
			Doc:  "// Diff compares the set of messages on the sender with the set of\n// messages on the receiver. The sender streams batches of message IDs\n// and the receiver reponds with one bool for each message ID. A true\n// value means the receiver has the message, a false value means it\n// doesn't.",
		},
		{
			Name: "Push",
			Doc:  "// Push accepts a message. The receiver may be the final recipient\n// or a relay. If the receiver has already seen this message or\n// if it cannot relay the message, it should return a error.\n//\n// The message content is streamed to the receiver. The content is\n// opaque to everyone except the final recipient.",
			InArgs: []rpc.ArgDesc{
				{"Msg", ``},    // Message
				{"Offset", ``}, // int64
			},
		},
		{
			Name: "ResumeOffset",
			Doc:  "// ResumeOffset returns the size of the partially transferred message.\n// The caller will use it to resume the transfer. If the message doesn't\n// exist yet, the returned offset will be 0.",
			InArgs: []rpc.ArgDesc{
				{"Msg", ``}, // Message
			},
			OutArgs: []rpc.ArgDesc{
				{"Offset", ``}, // int64
			},
		},
	},
}

// MessengerDiffServerStream is the server stream for Messenger.Diff.
type MessengerDiffServerStream interface {
	// RecvStream returns the receiver side of the Messenger.Diff 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() []string
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
	// SendStream returns the send side of the Messenger.Diff 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 []bool) error
	}
}

// MessengerDiffServerCall represents the context passed to Messenger.Diff.
type MessengerDiffServerCall interface {
	rpc.ServerCall
	MessengerDiffServerStream
}

// MessengerDiffServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements MessengerDiffServerCall.
type MessengerDiffServerCallStub struct {
	rpc.StreamServerCall
	valRecv []string
	errRecv error
}

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

// RecvStream returns the receiver side of the Messenger.Diff server stream.
func (s *MessengerDiffServerCallStub) RecvStream() interface {
	Advance() bool
	Value() []string
	Err() error
} {
	return implMessengerDiffServerCallRecv{s}
}

type implMessengerDiffServerCallRecv struct {
	s *MessengerDiffServerCallStub
}

func (s implMessengerDiffServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implMessengerDiffServerCallRecv) Value() []string {
	return s.s.valRecv
}
func (s implMessengerDiffServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}

// SendStream returns the send side of the Messenger.Diff server stream.
func (s *MessengerDiffServerCallStub) SendStream() interface {
	Send(item []bool) error
} {
	return implMessengerDiffServerCallSend{s}
}

type implMessengerDiffServerCallSend struct {
	s *MessengerDiffServerCallStub
}

func (s implMessengerDiffServerCallSend) Send(item []bool) error {
	return s.s.Send(item)
}

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

// MessengerPushServerCall represents the context passed to Messenger.Push.
type MessengerPushServerCall interface {
	rpc.ServerCall
	MessengerPushServerStream
}

// MessengerPushServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements MessengerPushServerCall.
type MessengerPushServerCallStub struct {
	rpc.StreamServerCall
	valRecv []byte
	errRecv error
}

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

// RecvStream returns the receiver side of the Messenger.Push server stream.
func (s *MessengerPushServerCallStub) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implMessengerPushServerCallRecv{s}
}

type implMessengerPushServerCallRecv struct {
	s *MessengerPushServerCallStub
}

func (s implMessengerPushServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implMessengerPushServerCallRecv) Value() []byte {
	return s.s.valRecv
}
func (s implMessengerPushServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}

// MessageRepositoryClientMethods is the client interface
// containing MessageRepository methods.
//
// MessageRepository defines the interface to talk to a node that holds
// messages.
// This interface is EXPERIMENTAL and can change at any time.
type MessageRepositoryClientMethods interface {
	// Manifest shows all messages in the receiver's repository.
	Manifest(*context.T, ...rpc.CallOpt) (MessageRepositoryManifestClientCall, error)
	// Pull retrieves the message with the given ID. The message content
	// is streamed to the caller.
	Pull(_ *context.T, Id string, Offset int64, _ ...rpc.CallOpt) (MessageRepositoryPullClientCall, error)
}

// MessageRepositoryClientStub adds universal methods to MessageRepositoryClientMethods.
type MessageRepositoryClientStub interface {
	MessageRepositoryClientMethods
	rpc.UniversalServiceMethods
}

// MessageRepositoryClient returns a client stub for MessageRepository.
func MessageRepositoryClient(name string) MessageRepositoryClientStub {
	return implMessageRepositoryClientStub{name}
}

type implMessageRepositoryClientStub struct {
	name string
}

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

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

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

// MessageRepositoryManifestClientCall represents the call returned from MessageRepository.Manifest.
type MessageRepositoryManifestClientCall interface {
	MessageRepositoryManifestClientStream
	// 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 implMessageRepositoryManifestClientCall struct {
	rpc.ClientCall
	valRecv Message
	errRecv error
}

func (c *implMessageRepositoryManifestClientCall) RecvStream() interface {
	Advance() bool
	Value() Message
	Err() error
} {
	return implMessageRepositoryManifestClientCallRecv{c}
}

type implMessageRepositoryManifestClientCallRecv struct {
	c *implMessageRepositoryManifestClientCall
}

func (c implMessageRepositoryManifestClientCallRecv) Advance() bool {
	c.c.valRecv = Message{}
	c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c implMessageRepositoryManifestClientCallRecv) Value() Message {
	return c.c.valRecv
}
func (c implMessageRepositoryManifestClientCallRecv) Err() error {
	if c.c.errRecv == io.EOF {
		return nil
	}
	return c.c.errRecv
}
func (c *implMessageRepositoryManifestClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// MessageRepositoryPullClientStream is the client stream for MessageRepository.Pull.
type MessageRepositoryPullClientStream interface {
	// RecvStream returns the receiver side of the MessageRepository.Pull 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
	}
}

// MessageRepositoryPullClientCall represents the call returned from MessageRepository.Pull.
type MessageRepositoryPullClientCall interface {
	MessageRepositoryPullClientStream
	// 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() (Message, error)
}

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

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

type implMessageRepositoryPullClientCallRecv struct {
	c *implMessageRepositoryPullClientCall
}

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

// MessageRepositoryServerMethods is the interface a server writer
// implements for MessageRepository.
//
// MessageRepository defines the interface to talk to a node that holds
// messages.
// This interface is EXPERIMENTAL and can change at any time.
type MessageRepositoryServerMethods interface {
	// Manifest shows all messages in the receiver's repository.
	Manifest(*context.T, MessageRepositoryManifestServerCall) error
	// Pull retrieves the message with the given ID. The message content
	// is streamed to the caller.
	Pull(_ *context.T, _ MessageRepositoryPullServerCall, Id string, Offset int64) (Message, error)
}

// MessageRepositoryServerStubMethods is the server interface containing
// MessageRepository methods, as expected by rpc.Server.
// The only difference between this interface and MessageRepositoryServerMethods
// is the streaming methods.
type MessageRepositoryServerStubMethods interface {
	// Manifest shows all messages in the receiver's repository.
	Manifest(*context.T, *MessageRepositoryManifestServerCallStub) error
	// Pull retrieves the message with the given ID. The message content
	// is streamed to the caller.
	Pull(_ *context.T, _ *MessageRepositoryPullServerCallStub, Id string, Offset int64) (Message, error)
}

// MessageRepositoryServerStub adds universal methods to MessageRepositoryServerStubMethods.
type MessageRepositoryServerStub interface {
	MessageRepositoryServerStubMethods
	// Describe the MessageRepository interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implMessageRepositoryServerStub) Manifest(ctx *context.T, call *MessageRepositoryManifestServerCallStub) error {
	return s.impl.Manifest(ctx, call)
}

func (s implMessageRepositoryServerStub) Pull(ctx *context.T, call *MessageRepositoryPullServerCallStub, i0 string, i1 int64) (Message, error) {
	return s.impl.Pull(ctx, call, i0, i1)
}

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

func (s implMessageRepositoryServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{MessageRepositoryDesc}
}

// MessageRepositoryDesc describes the MessageRepository interface.
var MessageRepositoryDesc rpc.InterfaceDesc = descMessageRepository

// descMessageRepository hides the desc to keep godoc clean.
var descMessageRepository = rpc.InterfaceDesc{
	Name:    "MessageRepository",
	PkgPath: "messenger/ifc",
	Doc:     "// MessageRepository defines the interface to talk to a node that holds\n// messages.\n// This interface is EXPERIMENTAL and can change at any time.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Manifest",
			Doc:  "// Manifest shows all messages in the receiver's repository.",
		},
		{
			Name: "Pull",
			Doc:  "// Pull retrieves the message with the given ID. The message content\n// is streamed to the caller.",
			InArgs: []rpc.ArgDesc{
				{"Id", ``},     // string
				{"Offset", ``}, // int64
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // Message
			},
		},
	},
}

// MessageRepositoryManifestServerStream is the server stream for MessageRepository.Manifest.
type MessageRepositoryManifestServerStream interface {
	// SendStream returns the send side of the MessageRepository.Manifest 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 Message) error
	}
}

// MessageRepositoryManifestServerCall represents the context passed to MessageRepository.Manifest.
type MessageRepositoryManifestServerCall interface {
	rpc.ServerCall
	MessageRepositoryManifestServerStream
}

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

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

// SendStream returns the send side of the MessageRepository.Manifest server stream.
func (s *MessageRepositoryManifestServerCallStub) SendStream() interface {
	Send(item Message) error
} {
	return implMessageRepositoryManifestServerCallSend{s}
}

type implMessageRepositoryManifestServerCallSend struct {
	s *MessageRepositoryManifestServerCallStub
}

func (s implMessageRepositoryManifestServerCallSend) Send(item Message) error {
	return s.s.Send(item)
}

// MessageRepositoryPullServerStream is the server stream for MessageRepository.Pull.
type MessageRepositoryPullServerStream interface {
	// SendStream returns the send side of the MessageRepository.Pull 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
	}
}

// MessageRepositoryPullServerCall represents the context passed to MessageRepository.Pull.
type MessageRepositoryPullServerCall interface {
	rpc.ServerCall
	MessageRepositoryPullServerStream
}

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

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

// SendStream returns the send side of the MessageRepository.Pull server stream.
func (s *MessageRepositoryPullServerCallStub) SendStream() interface {
	Send(item []byte) error
} {
	return implMessageRepositoryPullServerCallSend{s}
}

type implMessageRepositoryPullServerCallSend struct {
	s *MessageRepositoryPullServerCallStub
}

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

// MessengerRepositoryClientMethods is the client interface
// containing MessengerRepository methods.
//
// MessengerRepository combines the Messenger and MessageRepository interfaces.
type MessengerRepositoryClientMethods interface {
	// Messenger defines the interface to talk to nodes that can relay messages.
	// This interface is EXPERIMENTAL and can change at any time.
	MessengerClientMethods
	// MessageRepository defines the interface to talk to a node that holds
	// messages.
	// This interface is EXPERIMENTAL and can change at any time.
	MessageRepositoryClientMethods
}

// MessengerRepositoryClientStub adds universal methods to MessengerRepositoryClientMethods.
type MessengerRepositoryClientStub interface {
	MessengerRepositoryClientMethods
	rpc.UniversalServiceMethods
}

// MessengerRepositoryClient returns a client stub for MessengerRepository.
func MessengerRepositoryClient(name string) MessengerRepositoryClientStub {
	return implMessengerRepositoryClientStub{name, MessengerClient(name), MessageRepositoryClient(name)}
}

type implMessengerRepositoryClientStub struct {
	name string

	MessengerClientStub
	MessageRepositoryClientStub
}

// MessengerRepositoryServerMethods is the interface a server writer
// implements for MessengerRepository.
//
// MessengerRepository combines the Messenger and MessageRepository interfaces.
type MessengerRepositoryServerMethods interface {
	// Messenger defines the interface to talk to nodes that can relay messages.
	// This interface is EXPERIMENTAL and can change at any time.
	MessengerServerMethods
	// MessageRepository defines the interface to talk to a node that holds
	// messages.
	// This interface is EXPERIMENTAL and can change at any time.
	MessageRepositoryServerMethods
}

// MessengerRepositoryServerStubMethods is the server interface containing
// MessengerRepository methods, as expected by rpc.Server.
// The only difference between this interface and MessengerRepositoryServerMethods
// is the streaming methods.
type MessengerRepositoryServerStubMethods interface {
	// Messenger defines the interface to talk to nodes that can relay messages.
	// This interface is EXPERIMENTAL and can change at any time.
	MessengerServerStubMethods
	// MessageRepository defines the interface to talk to a node that holds
	// messages.
	// This interface is EXPERIMENTAL and can change at any time.
	MessageRepositoryServerStubMethods
}

// MessengerRepositoryServerStub adds universal methods to MessengerRepositoryServerStubMethods.
type MessengerRepositoryServerStub interface {
	MessengerRepositoryServerStubMethods
	// Describe the MessengerRepository interfaces.
	Describe__() []rpc.InterfaceDesc
}

// MessengerRepositoryServer returns a server stub for MessengerRepository.
// It converts an implementation of MessengerRepositoryServerMethods into
// an object that may be used by rpc.Server.
func MessengerRepositoryServer(impl MessengerRepositoryServerMethods) MessengerRepositoryServerStub {
	stub := implMessengerRepositoryServerStub{
		impl:                        impl,
		MessengerServerStub:         MessengerServer(impl),
		MessageRepositoryServerStub: MessageRepositoryServer(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 implMessengerRepositoryServerStub struct {
	impl MessengerRepositoryServerMethods
	MessengerServerStub
	MessageRepositoryServerStub
	gs *rpc.GlobState
}

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

func (s implMessengerRepositoryServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{MessengerRepositoryDesc, MessengerDesc, MessageRepositoryDesc}
}

// MessengerRepositoryDesc describes the MessengerRepository interface.
var MessengerRepositoryDesc rpc.InterfaceDesc = descMessengerRepository

// descMessengerRepository hides the desc to keep godoc clean.
var descMessengerRepository = rpc.InterfaceDesc{
	Name:    "MessengerRepository",
	PkgPath: "messenger/ifc",
	Doc:     "// MessengerRepository combines the Messenger and MessageRepository interfaces.",
	Embeds: []rpc.EmbedDesc{
		{"Messenger", "messenger/ifc", "// Messenger defines the interface to talk to nodes that can relay messages.\n// This interface is EXPERIMENTAL and can change at any time."},
		{"MessageRepository", "messenger/ifc", "// MessageRepository defines the interface to talk to a node that holds\n// messages.\n// This interface is EXPERIMENTAL and can change at any time."},
	},
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1 *vdl.Type
	__VDLType_list_2   *vdl.Type
	__VDLType_struct_3 *vdl.Type
	__VDLType_map_4    *vdl.Type
	__VDLType_struct_5 *vdl.Type
	__VDLType_struct_6 *vdl.Type
	__VDLType_struct_7 *vdl.Type
	__VDLType_list_8   *vdl.Type
	__VDLType_union_9  *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((*Message)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*Message)(nil)).Elem()
	__VDLType_list_2 = vdl.TypeOf((*[]string)(nil))
	__VDLType_struct_3 = vdl.TypeOf((*security.WireBlessings)(nil)).Elem()
	__VDLType_map_4 = vdl.TypeOf((*map[string]security.Discharge)(nil))
	__VDLType_struct_5 = vdl.TypeOf((*security.Signature)(nil)).Elem()
	__VDLType_struct_6 = vdl.TypeOf((*vdltime.Time)(nil)).Elem()
	__VDLType_struct_7 = vdl.TypeOf((*vdltime.Duration)(nil)).Elem()
	__VDLType_list_8 = vdl.TypeOf((*[]byte)(nil))
	__VDLType_union_9 = vdl.TypeOf((*security.WireDischarge)(nil))

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrAlreadySeen.ID), "{1:}{2:} message id already seen: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBusy.ID), "{1:}{2:} message is already opened")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrContentMismatch.ID), "{1:}{2:} the sha256 hash doesn't match the message content")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrExpired.ID), "{1:}{2:} message lifespan expired: {3} + {4} < {5}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrIncorrectOffset.ID), "{1:}{2:} the specified file offset is incorrect ({3} != {4})")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidSignature.ID), "{1:}{2:} message signature is invalid")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrMessageIdCollision.ID), "{1:}{2:} message id already seen with different content: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoRoute.ID), "{1:}{2:} no route for recipient: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrRateLimitExceeded.ID), "{1:}{2:} request rate limit exceeded: {3} req/s")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrTooBig.ID), "{1:}{2:} message is too big, limit: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrTooManyHops.ID), "{1:}{2:} too many hops, limit: {3}")

	return struct{}{}
}
