// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by the vanadium vdl tool.
// Package: repository

// Package repository defines interfaces for storing and retrieving device,
// application and binary management related information.
package repository

import (
	"io"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/services/application"
	"v.io/v23/services/binary"
	"v.io/v23/services/permissions"
	"v.io/v23/services/tidyable"
	"v.io/v23/vdl"
)

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

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

// MediaInfo contains the metadata information for a binary.
type MediaInfo struct {
	Type     string // The media-type (RFC 2046)
	Encoding string // The file encoding is optional and can be either "gzip" or "bzip2".
}

func (MediaInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/repository.MediaInfo"`
}) {
}

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

func (x MediaInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if x.Type != "" {
		if err := enc.NextFieldValueString(0, vdl.StringType, x.Type); err != nil {
			return err
		}
	}
	if x.Encoding != "" {
		if err := enc.NextFieldValueString(1, vdl.StringType, x.Encoding); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *MediaInfo) VDLRead(dec vdl.Decoder) error {
	*x = MediaInfo{}
	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:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Type = value
			}
		case 1:
			switch value, err := dec.ReadValueString(); {
			case err != nil:
				return err
			default:
				x.Encoding = value
			}
		}
	}
}

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

// ApplicationClientMethods is the client interface
// containing Application methods.
//
// Application provides access to application envelopes. An
// application envelope is identified by an application name and an
// application version, which are specified through the object name,
// and a profile name, which is specified using a method argument.
//
// Example:
// /apps/search/v1.Match([]string{"base", "media"})
//   returns an application envelope that can be used for downloading
//   and executing the "search" application, version "v1", runnable
//   on either the "base" or "media" profile.
type ApplicationClientMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectClientMethods
	// Tidyable specifies that a service can be tidied.
	tidyable.TidyableClientMethods
	// Match checks if any of the given profiles contains an application
	// envelope for the given application version (specified through the
	// object name suffix) and if so, returns this envelope. If multiple
	// profile matches are possible, the method returns the first
	// matching profile, respecting the order of the input argument.
	//
	// If the version is not specified in the suffix, the envelope
	// corresponding to the latest version that matches any of the given
	// profiles is returned.  If several profiles match this version, the
	// envelope for the first matching profile is returned, respecting the
	// order of the input argument.
	Match(_ *context.T, profiles []string, _ ...rpc.CallOpt) (application.Envelope, error)
}

// ApplicationClientStub adds universal methods to ApplicationClientMethods.
type ApplicationClientStub interface {
	ApplicationClientMethods
	rpc.UniversalServiceMethods
}

// ApplicationClient returns a client stub for Application.
func ApplicationClient(name string) ApplicationClientStub {
	return implApplicationClientStub{name, permissions.ObjectClient(name), tidyable.TidyableClient(name)}
}

type implApplicationClientStub struct {
	name string

	permissions.ObjectClientStub
	tidyable.TidyableClientStub
}

func (c implApplicationClientStub) Match(ctx *context.T, i0 []string, opts ...rpc.CallOpt) (o0 application.Envelope, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Match", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

// ApplicationServerMethods is the interface a server writer
// implements for Application.
//
// Application provides access to application envelopes. An
// application envelope is identified by an application name and an
// application version, which are specified through the object name,
// and a profile name, which is specified using a method argument.
//
// Example:
// /apps/search/v1.Match([]string{"base", "media"})
//   returns an application envelope that can be used for downloading
//   and executing the "search" application, version "v1", runnable
//   on either the "base" or "media" profile.
type ApplicationServerMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerMethods
	// Tidyable specifies that a service can be tidied.
	tidyable.TidyableServerMethods
	// Match checks if any of the given profiles contains an application
	// envelope for the given application version (specified through the
	// object name suffix) and if so, returns this envelope. If multiple
	// profile matches are possible, the method returns the first
	// matching profile, respecting the order of the input argument.
	//
	// If the version is not specified in the suffix, the envelope
	// corresponding to the latest version that matches any of the given
	// profiles is returned.  If several profiles match this version, the
	// envelope for the first matching profile is returned, respecting the
	// order of the input argument.
	Match(_ *context.T, _ rpc.ServerCall, profiles []string) (application.Envelope, error)
}

// ApplicationServerStubMethods is the server interface containing
// Application methods, as expected by rpc.Server.
// There is no difference between this interface and ApplicationServerMethods
// since there are no streaming methods.
type ApplicationServerStubMethods ApplicationServerMethods

// ApplicationServerStub adds universal methods to ApplicationServerStubMethods.
type ApplicationServerStub interface {
	ApplicationServerStubMethods
	// Describe the Application interfaces.
	Describe__() []rpc.InterfaceDesc
}

// ApplicationServer returns a server stub for Application.
// It converts an implementation of ApplicationServerMethods into
// an object that may be used by rpc.Server.
func ApplicationServer(impl ApplicationServerMethods) ApplicationServerStub {
	stub := implApplicationServerStub{
		impl:               impl,
		ObjectServerStub:   permissions.ObjectServer(impl),
		TidyableServerStub: tidyable.TidyableServer(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 implApplicationServerStub struct {
	impl ApplicationServerMethods
	permissions.ObjectServerStub
	tidyable.TidyableServerStub
	gs *rpc.GlobState
}

func (s implApplicationServerStub) Match(ctx *context.T, call rpc.ServerCall, i0 []string) (application.Envelope, error) {
	return s.impl.Match(ctx, call, i0)
}

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

func (s implApplicationServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ApplicationDesc, permissions.ObjectDesc, tidyable.TidyableDesc}
}

// ApplicationDesc describes the Application interface.
var ApplicationDesc rpc.InterfaceDesc = descApplication

// descApplication hides the desc to keep godoc clean.
var descApplication = rpc.InterfaceDesc{
	Name:    "Application",
	PkgPath: "v.io/v23/services/repository",
	Doc:     "// Application provides access to application envelopes. An\n// application envelope is identified by an application name and an\n// application version, which are specified through the object name,\n// and a profile name, which is specified using a method argument.\n//\n// Example:\n// /apps/search/v1.Match([]string{\"base\", \"media\"})\n//   returns an application envelope that can be used for downloading\n//   and executing the \"search\" application, version \"v1\", runnable\n//   on either the \"base\" or \"media\" profile.",
	Embeds: []rpc.EmbedDesc{
		{"Object", "v.io/v23/services/permissions", "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"},
		{"Tidyable", "v.io/v23/services/tidyable", "// Tidyable specifies that a service can be tidied."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Match",
			Doc:  "// Match checks if any of the given profiles contains an application\n// envelope for the given application version (specified through the\n// object name suffix) and if so, returns this envelope. If multiple\n// profile matches are possible, the method returns the first\n// matching profile, respecting the order of the input argument.\n//\n// If the version is not specified in the suffix, the envelope\n// corresponding to the latest version that matches any of the given\n// profiles is returned.  If several profiles match this version, the\n// envelope for the first matching profile is returned, respecting the\n// order of the input argument.",
			InArgs: []rpc.ArgDesc{
				{"profiles", ``}, // []string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // application.Envelope
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// BinaryClientMethods is the client interface
// containing Binary methods.
//
// Binary can be used to store and retrieve vanadium application
// binaries.
//
// To create a binary, clients first invoke the Create() method that
// specifies the number of parts the binary consists of. Clients then
// uploads the individual parts through the Upload() method, which
// identifies the part being uploaded. To resume an upload after a
// failure, clients invoke the UploadStatus() method, which returns a
// slice that identifies which parts are missing.
//
// To download a binary, clients first invoke Stat(), which returns
// information describing the binary, including the number of parts
// the binary consists of. Clients then download the individual parts
// through the Download() method, which identifies the part being
// downloaded. Alternatively, clients can download the binary through
// HTTP using a transient URL available through the DownloadUrl()
// method.
//
// To delete the binary, clients invoke the Delete() method.
type BinaryClientMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectClientMethods
	// Create expresses the intent to create a binary identified by the
	// object name suffix consisting of the given number of parts. The
	// mediaInfo argument contains metadata for the binary. If the suffix
	// identifies a binary that has already been created, the method
	// returns an error.
	Create(_ *context.T, nparts int32, mediaInfo MediaInfo, _ ...rpc.CallOpt) error
	// Delete deletes the binary identified by the object name
	// suffix. If the binary that has not been created, the method
	// returns an error.
	Delete(*context.T, ...rpc.CallOpt) error
	// Download opens a stream that can used for downloading the given
	// part of the binary identified by the object name suffix. If the
	// binary part has not been uploaded, the method returns an
	// error. If the Delete() method is invoked when the Download()
	// method is in progress, the outcome the Download() method is
	// undefined.
	Download(_ *context.T, part int32, _ ...rpc.CallOpt) (BinaryDownloadClientCall, error)
	// DownloadUrl returns a transient URL from which the binary
	// identified by the object name suffix can be downloaded using the
	// HTTP protocol. If not all parts of the binary have been uploaded,
	// the method returns an error.
	DownloadUrl(*context.T, ...rpc.CallOpt) (url string, ttl int64, _ error)
	// Stat returns information describing the parts of the binary
	// identified by the object name suffix, and its RFC 2046 media type.
	// If the binary has not been created, the method returns an error.
	Stat(*context.T, ...rpc.CallOpt) (Parts []binary.PartInfo, MediaInfo MediaInfo, _ error)
	// Upload opens a stream that can be used for uploading the given
	// part of the binary identified by the object name suffix. If the
	// binary has not been created, the method returns an error. If the
	// binary part has been uploaded, the method returns an error. If
	// the same binary part is being uploaded by another caller, the
	// method returns an error.
	Upload(_ *context.T, part int32, _ ...rpc.CallOpt) (BinaryUploadClientCall, error)
}

// BinaryClientStub adds universal methods to BinaryClientMethods.
type BinaryClientStub interface {
	BinaryClientMethods
	rpc.UniversalServiceMethods
}

// BinaryClient returns a client stub for Binary.
func BinaryClient(name string) BinaryClientStub {
	return implBinaryClientStub{name, permissions.ObjectClient(name)}
}

type implBinaryClientStub struct {
	name string

	permissions.ObjectClientStub
}

func (c implBinaryClientStub) Create(ctx *context.T, i0 int32, i1 MediaInfo, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Create", []interface{}{i0, i1}, nil, opts...)
	return
}

func (c implBinaryClientStub) Delete(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Delete", nil, nil, opts...)
	return
}

func (c implBinaryClientStub) Download(ctx *context.T, i0 int32, opts ...rpc.CallOpt) (ocall BinaryDownloadClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Download", []interface{}{i0}, opts...); err != nil {
		return
	}
	ocall = &implBinaryDownloadClientCall{ClientCall: call}
	return
}

func (c implBinaryClientStub) DownloadUrl(ctx *context.T, opts ...rpc.CallOpt) (o0 string, o1 int64, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "DownloadUrl", nil, []interface{}{&o0, &o1}, opts...)
	return
}

func (c implBinaryClientStub) Stat(ctx *context.T, opts ...rpc.CallOpt) (o0 []binary.PartInfo, o1 MediaInfo, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Stat", nil, []interface{}{&o0, &o1}, opts...)
	return
}

func (c implBinaryClientStub) Upload(ctx *context.T, i0 int32, opts ...rpc.CallOpt) (ocall BinaryUploadClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "Upload", []interface{}{i0}, opts...); err != nil {
		return
	}
	ocall = &implBinaryUploadClientCall{ClientCall: call}
	return
}

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

// BinaryDownloadClientCall represents the call returned from Binary.Download.
type BinaryDownloadClientCall interface {
	BinaryDownloadClientStream
	// 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 implBinaryDownloadClientCall struct {
	rpc.ClientCall
	valRecv []byte
	errRecv error
}

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

type implBinaryDownloadClientCallRecv struct {
	c *implBinaryDownloadClientCall
}

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

// BinaryUploadClientStream is the client stream for Binary.Upload.
type BinaryUploadClientStream interface {
	// SendStream returns the send side of the Binary.Upload 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
	}
}

// BinaryUploadClientCall represents the call returned from Binary.Upload.
type BinaryUploadClientCall interface {
	BinaryUploadClientStream
	// 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 implBinaryUploadClientCall struct {
	rpc.ClientCall
}

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

type implBinaryUploadClientCallSend struct {
	c *implBinaryUploadClientCall
}

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

// BinaryServerMethods is the interface a server writer
// implements for Binary.
//
// Binary can be used to store and retrieve vanadium application
// binaries.
//
// To create a binary, clients first invoke the Create() method that
// specifies the number of parts the binary consists of. Clients then
// uploads the individual parts through the Upload() method, which
// identifies the part being uploaded. To resume an upload after a
// failure, clients invoke the UploadStatus() method, which returns a
// slice that identifies which parts are missing.
//
// To download a binary, clients first invoke Stat(), which returns
// information describing the binary, including the number of parts
// the binary consists of. Clients then download the individual parts
// through the Download() method, which identifies the part being
// downloaded. Alternatively, clients can download the binary through
// HTTP using a transient URL available through the DownloadUrl()
// method.
//
// To delete the binary, clients invoke the Delete() method.
type BinaryServerMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerMethods
	// Create expresses the intent to create a binary identified by the
	// object name suffix consisting of the given number of parts. The
	// mediaInfo argument contains metadata for the binary. If the suffix
	// identifies a binary that has already been created, the method
	// returns an error.
	Create(_ *context.T, _ rpc.ServerCall, nparts int32, mediaInfo MediaInfo) error
	// Delete deletes the binary identified by the object name
	// suffix. If the binary that has not been created, the method
	// returns an error.
	Delete(*context.T, rpc.ServerCall) error
	// Download opens a stream that can used for downloading the given
	// part of the binary identified by the object name suffix. If the
	// binary part has not been uploaded, the method returns an
	// error. If the Delete() method is invoked when the Download()
	// method is in progress, the outcome the Download() method is
	// undefined.
	Download(_ *context.T, _ BinaryDownloadServerCall, part int32) error
	// DownloadUrl returns a transient URL from which the binary
	// identified by the object name suffix can be downloaded using the
	// HTTP protocol. If not all parts of the binary have been uploaded,
	// the method returns an error.
	DownloadUrl(*context.T, rpc.ServerCall) (url string, ttl int64, _ error)
	// Stat returns information describing the parts of the binary
	// identified by the object name suffix, and its RFC 2046 media type.
	// If the binary has not been created, the method returns an error.
	Stat(*context.T, rpc.ServerCall) (Parts []binary.PartInfo, MediaInfo MediaInfo, _ error)
	// Upload opens a stream that can be used for uploading the given
	// part of the binary identified by the object name suffix. If the
	// binary has not been created, the method returns an error. If the
	// binary part has been uploaded, the method returns an error. If
	// the same binary part is being uploaded by another caller, the
	// method returns an error.
	Upload(_ *context.T, _ BinaryUploadServerCall, part int32) error
}

// BinaryServerStubMethods is the server interface containing
// Binary methods, as expected by rpc.Server.
// The only difference between this interface and BinaryServerMethods
// is the streaming methods.
type BinaryServerStubMethods interface {
	// Object provides access control for Vanadium objects.
	//
	// Vanadium services implementing dynamic access control would typically embed
	// this interface and tag additional methods defined by the service with one of
	// Admin, Read, Write, Resolve etc. For example, the VDL definition of the
	// object would be:
	//
	//   package mypackage
	//
	//   import "v.io/v23/security/access"
	//   import "v.io/v23/services/permissions"
	//
	//   type MyObject interface {
	//     permissions.Object
	//     MyRead() (string, error) {access.Read}
	//     MyWrite(string) error    {access.Write}
	//   }
	//
	// If the set of pre-defined tags is insufficient, services may define their
	// own tag type and annotate all methods with this new type.
	//
	// Instead of embedding this Object interface, define SetPermissions and
	// GetPermissions in their own interface. Authorization policies will typically
	// respect annotations of a single type. For example, the VDL definition of an
	// object would be:
	//
	//  package mypackage
	//
	//  import "v.io/v23/security/access"
	//
	//  type MyTag string
	//
	//  const (
	//    Blue = MyTag("Blue")
	//    Red  = MyTag("Red")
	//  )
	//
	//  type MyObject interface {
	//    MyMethod() (string, error) {Blue}
	//
	//    // Allow clients to change access via the access.Object interface:
	//    SetPermissions(perms access.Permissions, version string) error         {Red}
	//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}
	//  }
	permissions.ObjectServerStubMethods
	// Create expresses the intent to create a binary identified by the
	// object name suffix consisting of the given number of parts. The
	// mediaInfo argument contains metadata for the binary. If the suffix
	// identifies a binary that has already been created, the method
	// returns an error.
	Create(_ *context.T, _ rpc.ServerCall, nparts int32, mediaInfo MediaInfo) error
	// Delete deletes the binary identified by the object name
	// suffix. If the binary that has not been created, the method
	// returns an error.
	Delete(*context.T, rpc.ServerCall) error
	// Download opens a stream that can used for downloading the given
	// part of the binary identified by the object name suffix. If the
	// binary part has not been uploaded, the method returns an
	// error. If the Delete() method is invoked when the Download()
	// method is in progress, the outcome the Download() method is
	// undefined.
	Download(_ *context.T, _ *BinaryDownloadServerCallStub, part int32) error
	// DownloadUrl returns a transient URL from which the binary
	// identified by the object name suffix can be downloaded using the
	// HTTP protocol. If not all parts of the binary have been uploaded,
	// the method returns an error.
	DownloadUrl(*context.T, rpc.ServerCall) (url string, ttl int64, _ error)
	// Stat returns information describing the parts of the binary
	// identified by the object name suffix, and its RFC 2046 media type.
	// If the binary has not been created, the method returns an error.
	Stat(*context.T, rpc.ServerCall) (Parts []binary.PartInfo, MediaInfo MediaInfo, _ error)
	// Upload opens a stream that can be used for uploading the given
	// part of the binary identified by the object name suffix. If the
	// binary has not been created, the method returns an error. If the
	// binary part has been uploaded, the method returns an error. If
	// the same binary part is being uploaded by another caller, the
	// method returns an error.
	Upload(_ *context.T, _ *BinaryUploadServerCallStub, part int32) error
}

// BinaryServerStub adds universal methods to BinaryServerStubMethods.
type BinaryServerStub interface {
	BinaryServerStubMethods
	// Describe the Binary interfaces.
	Describe__() []rpc.InterfaceDesc
}

// BinaryServer returns a server stub for Binary.
// It converts an implementation of BinaryServerMethods into
// an object that may be used by rpc.Server.
func BinaryServer(impl BinaryServerMethods) BinaryServerStub {
	stub := implBinaryServerStub{
		impl:             impl,
		ObjectServerStub: permissions.ObjectServer(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 implBinaryServerStub struct {
	impl BinaryServerMethods
	permissions.ObjectServerStub
	gs *rpc.GlobState
}

func (s implBinaryServerStub) Create(ctx *context.T, call rpc.ServerCall, i0 int32, i1 MediaInfo) error {
	return s.impl.Create(ctx, call, i0, i1)
}

func (s implBinaryServerStub) Delete(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.Delete(ctx, call)
}

func (s implBinaryServerStub) Download(ctx *context.T, call *BinaryDownloadServerCallStub, i0 int32) error {
	return s.impl.Download(ctx, call, i0)
}

func (s implBinaryServerStub) DownloadUrl(ctx *context.T, call rpc.ServerCall) (string, int64, error) {
	return s.impl.DownloadUrl(ctx, call)
}

func (s implBinaryServerStub) Stat(ctx *context.T, call rpc.ServerCall) ([]binary.PartInfo, MediaInfo, error) {
	return s.impl.Stat(ctx, call)
}

func (s implBinaryServerStub) Upload(ctx *context.T, call *BinaryUploadServerCallStub, i0 int32) error {
	return s.impl.Upload(ctx, call, i0)
}

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

func (s implBinaryServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{BinaryDesc, permissions.ObjectDesc}
}

// BinaryDesc describes the Binary interface.
var BinaryDesc rpc.InterfaceDesc = descBinary

// descBinary hides the desc to keep godoc clean.
var descBinary = rpc.InterfaceDesc{
	Name:    "Binary",
	PkgPath: "v.io/v23/services/repository",
	Doc:     "// Binary can be used to store and retrieve vanadium application\n// binaries.\n//\n// To create a binary, clients first invoke the Create() method that\n// specifies the number of parts the binary consists of. Clients then\n// uploads the individual parts through the Upload() method, which\n// identifies the part being uploaded. To resume an upload after a\n// failure, clients invoke the UploadStatus() method, which returns a\n// slice that identifies which parts are missing.\n//\n// To download a binary, clients first invoke Stat(), which returns\n// information describing the binary, including the number of parts\n// the binary consists of. Clients then download the individual parts\n// through the Download() method, which identifies the part being\n// downloaded. Alternatively, clients can download the binary through\n// HTTP using a transient URL available through the DownloadUrl()\n// method.\n//\n// To delete the binary, clients invoke the Delete() method.",
	Embeds: []rpc.EmbedDesc{
		{"Object", "v.io/v23/services/permissions", "// Object provides access control for Vanadium objects.\n//\n// Vanadium services implementing dynamic access control would typically embed\n// this interface and tag additional methods defined by the service with one of\n// Admin, Read, Write, Resolve etc. For example, the VDL definition of the\n// object would be:\n//\n//   package mypackage\n//\n//   import \"v.io/v23/security/access\"\n//   import \"v.io/v23/services/permissions\"\n//\n//   type MyObject interface {\n//     permissions.Object\n//     MyRead() (string, error) {access.Read}\n//     MyWrite(string) error    {access.Write}\n//   }\n//\n// If the set of pre-defined tags is insufficient, services may define their\n// own tag type and annotate all methods with this new type.\n//\n// Instead of embedding this Object interface, define SetPermissions and\n// GetPermissions in their own interface. Authorization policies will typically\n// respect annotations of a single type. For example, the VDL definition of an\n// object would be:\n//\n//  package mypackage\n//\n//  import \"v.io/v23/security/access\"\n//\n//  type MyTag string\n//\n//  const (\n//    Blue = MyTag(\"Blue\")\n//    Red  = MyTag(\"Red\")\n//  )\n//\n//  type MyObject interface {\n//    MyMethod() (string, error) {Blue}\n//\n//    // Allow clients to change access via the access.Object interface:\n//    SetPermissions(perms access.Permissions, version string) error         {Red}\n//    GetPermissions() (perms access.Permissions, version string, err error) {Blue}\n//  }"},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Create",
			Doc:  "// Create expresses the intent to create a binary identified by the\n// object name suffix consisting of the given number of parts. The\n// mediaInfo argument contains metadata for the binary. If the suffix\n// identifies a binary that has already been created, the method\n// returns an error.",
			InArgs: []rpc.ArgDesc{
				{"nparts", ``},    // int32
				{"mediaInfo", ``}, // MediaInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Delete",
			Doc:  "// Delete deletes the binary identified by the object name\n// suffix. If the binary that has not been created, the method\n// returns an error.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Download",
			Doc:  "// Download opens a stream that can used for downloading the given\n// part of the binary identified by the object name suffix. If the\n// binary part has not been uploaded, the method returns an\n// error. If the Delete() method is invoked when the Download()\n// method is in progress, the outcome the Download() method is\n// undefined.",
			InArgs: []rpc.ArgDesc{
				{"part", ``}, // int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "DownloadUrl",
			Doc:  "// DownloadUrl returns a transient URL from which the binary\n// identified by the object name suffix can be downloaded using the\n// HTTP protocol. If not all parts of the binary have been uploaded,\n// the method returns an error.",
			OutArgs: []rpc.ArgDesc{
				{"url", ``}, // string
				{"ttl", ``}, // int64
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Stat",
			Doc:  "// Stat returns information describing the parts of the binary\n// identified by the object name suffix, and its RFC 2046 media type.\n// If the binary has not been created, the method returns an error.",
			OutArgs: []rpc.ArgDesc{
				{"Parts", ``},     // []binary.PartInfo
				{"MediaInfo", ``}, // MediaInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Upload",
			Doc:  "// Upload opens a stream that can be used for uploading the given\n// part of the binary identified by the object name suffix. If the\n// binary has not been created, the method returns an error. If the\n// binary part has been uploaded, the method returns an error. If\n// the same binary part is being uploaded by another caller, the\n// method returns an error.",
			InArgs: []rpc.ArgDesc{
				{"part", ``}, // int32
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}

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

// BinaryDownloadServerCall represents the context passed to Binary.Download.
type BinaryDownloadServerCall interface {
	rpc.ServerCall
	BinaryDownloadServerStream
}

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

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

// SendStream returns the send side of the Binary.Download server stream.
func (s *BinaryDownloadServerCallStub) SendStream() interface {
	Send(item []byte) error
} {
	return implBinaryDownloadServerCallSend{s}
}

type implBinaryDownloadServerCallSend struct {
	s *BinaryDownloadServerCallStub
}

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

// BinaryUploadServerStream is the server stream for Binary.Upload.
type BinaryUploadServerStream interface {
	// RecvStream returns the receiver side of the Binary.Upload 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
	}
}

// BinaryUploadServerCall represents the context passed to Binary.Upload.
type BinaryUploadServerCall interface {
	rpc.ServerCall
	BinaryUploadServerStream
}

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

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

// RecvStream returns the receiver side of the Binary.Upload server stream.
func (s *BinaryUploadServerCallStub) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implBinaryUploadServerCallRecv{s}
}

type implBinaryUploadServerCallRecv struct {
	s *BinaryUploadServerCallStub
}

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

// ProfileClientMethods is the client interface
// containing Profile methods.
//
// Profile abstracts a device's ability to run binaries, and hides
// specifics such as the operating system, hardware architecture, and
// the set of installed libraries. Profiles describe binaries and
// devices, and are used to match them.
type ProfileClientMethods interface {
	// Label is the human-readable profile key for the profile,
	// e.g. "linux-media". The label can be used to uniquely identify
	// the profile (for the purpose of matching application binaries and
	// devices).
	Label(*context.T, ...rpc.CallOpt) (string, error)
	// Description is a free-text description of the profile, meant for
	// human consumption.
	Description(*context.T, ...rpc.CallOpt) (string, error)
}

// ProfileClientStub adds universal methods to ProfileClientMethods.
type ProfileClientStub interface {
	ProfileClientMethods
	rpc.UniversalServiceMethods
}

// ProfileClient returns a client stub for Profile.
func ProfileClient(name string) ProfileClientStub {
	return implProfileClientStub{name}
}

type implProfileClientStub struct {
	name string
}

func (c implProfileClientStub) Label(ctx *context.T, opts ...rpc.CallOpt) (o0 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Label", nil, []interface{}{&o0}, opts...)
	return
}

func (c implProfileClientStub) Description(ctx *context.T, opts ...rpc.CallOpt) (o0 string, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Description", nil, []interface{}{&o0}, opts...)
	return
}

// ProfileServerMethods is the interface a server writer
// implements for Profile.
//
// Profile abstracts a device's ability to run binaries, and hides
// specifics such as the operating system, hardware architecture, and
// the set of installed libraries. Profiles describe binaries and
// devices, and are used to match them.
type ProfileServerMethods interface {
	// Label is the human-readable profile key for the profile,
	// e.g. "linux-media". The label can be used to uniquely identify
	// the profile (for the purpose of matching application binaries and
	// devices).
	Label(*context.T, rpc.ServerCall) (string, error)
	// Description is a free-text description of the profile, meant for
	// human consumption.
	Description(*context.T, rpc.ServerCall) (string, error)
}

// ProfileServerStubMethods is the server interface containing
// Profile methods, as expected by rpc.Server.
// There is no difference between this interface and ProfileServerMethods
// since there are no streaming methods.
type ProfileServerStubMethods ProfileServerMethods

// ProfileServerStub adds universal methods to ProfileServerStubMethods.
type ProfileServerStub interface {
	ProfileServerStubMethods
	// Describe the Profile interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implProfileServerStub) Label(ctx *context.T, call rpc.ServerCall) (string, error) {
	return s.impl.Label(ctx, call)
}

func (s implProfileServerStub) Description(ctx *context.T, call rpc.ServerCall) (string, error) {
	return s.impl.Description(ctx, call)
}

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

func (s implProfileServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ProfileDesc}
}

// ProfileDesc describes the Profile interface.
var ProfileDesc rpc.InterfaceDesc = descProfile

// descProfile hides the desc to keep godoc clean.
var descProfile = rpc.InterfaceDesc{
	Name:    "Profile",
	PkgPath: "v.io/v23/services/repository",
	Doc:     "// Profile abstracts a device's ability to run binaries, and hides\n// specifics such as the operating system, hardware architecture, and\n// the set of installed libraries. Profiles describe binaries and\n// devices, and are used to match them.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Label",
			Doc:  "// Label is the human-readable profile key for the profile,\n// e.g. \"linux-media\". The label can be used to uniquely identify\n// the profile (for the purpose of matching application binaries and\n// devices).",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Description",
			Doc:  "// Description is a free-text description of the profile, meant for\n// human consumption.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1 *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((*MediaInfo)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*MediaInfo)(nil)).Elem()

	return struct{}{}
}
