// 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: discovery

package discovery

import (
	"fmt"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/discovery"
	"v.io/v23/i18n"
	"v.io/v23/rpc"
	"v.io/v23/security/access"
	"v.io/v23/vdl"
	"v.io/v23/vdl/vdlconv"
	"v.io/v23/verror"
)

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

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

type Uuid []byte

func (Uuid) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.Uuid"`
}) {
}

func (m *Uuid) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromBytes([]byte((*m)), tt); err != nil {
		return err
	}
	return nil
}

func (m *Uuid) MakeVDLTarget() vdl.Target {
	return &UuidTarget{Value: m}
}

type UuidTarget struct {
	Value *Uuid
	vdl.TargetBase
}

func (t *UuidTarget) FromBytes(src []byte, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*Uuid)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if len(src) == 0 {
		*t.Value = nil
	} else {
		*t.Value = make([]byte, len(src))
		copy(*t.Value, src)
	}

	return nil
}

func (x *Uuid) VDLRead(dec vdl.Decoder) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	var bytes []byte
	if err = dec.DecodeBytes(-1, &bytes); err != nil {
		return err
	}
	*x = bytes
	return dec.FinishValue()
}

type EncryptionAlgorithm int32

func (EncryptionAlgorithm) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.EncryptionAlgorithm"`
}) {
}

func (m *EncryptionAlgorithm) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromInt(int64((*m)), tt); err != nil {
		return err
	}
	return nil
}

func (m *EncryptionAlgorithm) MakeVDLTarget() vdl.Target {
	return &EncryptionAlgorithmTarget{Value: m}
}

type EncryptionAlgorithmTarget struct {
	Value *EncryptionAlgorithm
	vdl.TargetBase
}

func (t *EncryptionAlgorithmTarget) FromUint(src uint64, tt *vdl.Type) error {

	val, err := vdlconv.Uint64ToInt32(src)
	if err != nil {
		return err
	}
	*t.Value = EncryptionAlgorithm(val)

	return nil
}
func (t *EncryptionAlgorithmTarget) FromInt(src int64, tt *vdl.Type) error {

	val, err := vdlconv.Int64ToInt32(src)
	if err != nil {
		return err
	}
	*t.Value = EncryptionAlgorithm(val)

	return nil
}
func (t *EncryptionAlgorithmTarget) FromFloat(src float64, tt *vdl.Type) error {

	val, err := vdlconv.Float64ToInt32(src)
	if err != nil {
		return err
	}
	*t.Value = EncryptionAlgorithm(val)

	return nil
}

func (x *EncryptionAlgorithm) VDLRead(dec vdl.Decoder) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	tmp, err := dec.DecodeInt(32)
	if err != nil {
		return err
	}
	*x = EncryptionAlgorithm(tmp)
	return dec.FinishValue()
}

type EncryptionKey []byte

func (EncryptionKey) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.EncryptionKey"`
}) {
}

func (m *EncryptionKey) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromBytes([]byte((*m)), tt); err != nil {
		return err
	}
	return nil
}

func (m *EncryptionKey) MakeVDLTarget() vdl.Target {
	return &EncryptionKeyTarget{Value: m}
}

type EncryptionKeyTarget struct {
	Value *EncryptionKey
	vdl.TargetBase
}

func (t *EncryptionKeyTarget) FromBytes(src []byte, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*EncryptionKey)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if len(src) == 0 {
		*t.Value = nil
	} else {
		*t.Value = make([]byte, len(src))
		copy(*t.Value, src)
	}

	return nil
}

func (x *EncryptionKey) VDLRead(dec vdl.Decoder) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	var bytes []byte
	if err = dec.DecodeBytes(-1, &bytes); err != nil {
		return err
	}
	*x = bytes
	return dec.FinishValue()
}

type AdStatus byte

func (AdStatus) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.AdStatus"`
}) {
}

func (m *AdStatus) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromUint(uint64((*m)), tt); err != nil {
		return err
	}
	return nil
}

func (m *AdStatus) MakeVDLTarget() vdl.Target {
	return &AdStatusTarget{Value: m}
}

type AdStatusTarget struct {
	Value *AdStatus
	vdl.TargetBase
}

func (t *AdStatusTarget) FromUint(src uint64, tt *vdl.Type) error {

	val, err := vdlconv.Uint64ToUint8(src)
	if err != nil {
		return err
	}
	*t.Value = AdStatus(val)

	return nil
}
func (t *AdStatusTarget) FromInt(src int64, tt *vdl.Type) error {

	val, err := vdlconv.Int64ToUint8(src)
	if err != nil {
		return err
	}
	*t.Value = AdStatus(val)

	return nil
}
func (t *AdStatusTarget) FromFloat(src float64, tt *vdl.Type) error {

	val, err := vdlconv.Float64ToUint8(src)
	if err != nil {
		return err
	}
	*t.Value = AdStatus(val)

	return nil
}

func (x *AdStatus) VDLRead(dec vdl.Decoder) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	tmp, err := dec.DecodeUint(8)
	if err != nil {
		return err
	}
	*x = AdStatus(tmp)
	return dec.FinishValue()
}

// An AdHash is a hash of an advertisement.
type AdHash [8]byte

func (AdHash) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.AdHash"`
}) {
}

func (m *AdHash) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromBytes([]byte((*m)[:]), tt); err != nil {
		return err
	}
	return nil
}

func (m *AdHash) MakeVDLTarget() vdl.Target {
	return &AdHashTarget{Value: m}
}

type AdHashTarget struct {
	Value *AdHash
	vdl.TargetBase
}

func (t *AdHashTarget) FromBytes(src []byte, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*AdHash)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	copy((*t.Value)[:], src)

	return nil
}

func (x *AdHash) VDLRead(dec vdl.Decoder) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	bytes := x[:]
	if err = dec.DecodeBytes(8, &bytes); err != nil {
		return err
	}
	return dec.FinishValue()
}

// AdInfo represents advertisement information for discovery.
type AdInfo struct {
	Ad discovery.Advertisement
	// Type of encryption applied to the advertisement so that it can
	// only be decoded by authorized principals.
	EncryptionAlgorithm EncryptionAlgorithm
	// If the advertisement is encrypted, then the data required to
	// decrypt it. The format of this data is a function of the algorithm.
	EncryptionKeys []EncryptionKey
	// Hash of the current advertisement. This does not include the fields below.
	Hash AdHash
	// The addresses (vanadium object names) that the advertisement directory service
	// is served on. See directory.vdl.
	DirAddrs []string
	// Status of the current advertisement. Valid for scanned advertisements.
	Status AdStatus
	// TODO(jhahn): Add proximity.
	// TODO(jhahn): Use proximity for Lost.
	Lost bool
}

func (AdInfo) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/lib/discovery.AdInfo"`
}) {
}

func (m *AdInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := true
	var5 := (m.Ad.Id == discovery.AdId{})
	var4 = var4 && var5
	var6 := (m.Ad.InterfaceName == "")
	var4 = var4 && var6
	var var7 bool
	if len(m.Ad.Addresses) == 0 {
		var7 = true
	}
	var4 = var4 && var7
	var var8 bool
	if len(m.Ad.Attributes) == 0 {
		var8 = true
	}
	var4 = var4 && var8
	var var9 bool
	if len(m.Ad.Attachments) == 0 {
		var9 = true
	}
	var4 = var4 && var9
	if var4 {
		if err := fieldsTarget1.ZeroField("Ad"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Ad")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Ad.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var12 := (m.EncryptionAlgorithm == EncryptionAlgorithm(0))
	if var12 {
		if err := fieldsTarget1.ZeroField("EncryptionAlgorithm"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget10, fieldTarget11, err := fieldsTarget1.StartField("EncryptionAlgorithm")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.EncryptionAlgorithm.FillVDLTarget(fieldTarget11, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget10, fieldTarget11); err != nil {
				return err
			}
		}
	}
	var var15 bool
	if len(m.EncryptionKeys) == 0 {
		var15 = true
	}
	if var15 {
		if err := fieldsTarget1.ZeroField("EncryptionKeys"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget13, fieldTarget14, err := fieldsTarget1.StartField("EncryptionKeys")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget16, err := fieldTarget14.StartList(tt.NonOptional().Field(2).Type, len(m.EncryptionKeys))
			if err != nil {
				return err
			}
			for i, elem18 := range m.EncryptionKeys {
				elemTarget17, err := listTarget16.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem18.FillVDLTarget(elemTarget17, tt.NonOptional().Field(2).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget16.FinishElem(elemTarget17); err != nil {
					return err
				}
			}
			if err := fieldTarget14.FinishList(listTarget16); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget13, fieldTarget14); err != nil {
				return err
			}
		}
	}
	var21 := (m.Hash == AdHash{})
	if var21 {
		if err := fieldsTarget1.ZeroField("Hash"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget19, fieldTarget20, err := fieldsTarget1.StartField("Hash")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Hash.FillVDLTarget(fieldTarget20, tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget19, fieldTarget20); err != nil {
				return err
			}
		}
	}
	var var24 bool
	if len(m.DirAddrs) == 0 {
		var24 = true
	}
	if var24 {
		if err := fieldsTarget1.ZeroField("DirAddrs"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget22, fieldTarget23, err := fieldsTarget1.StartField("DirAddrs")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget25, err := fieldTarget23.StartList(tt.NonOptional().Field(4).Type, len(m.DirAddrs))
			if err != nil {
				return err
			}
			for i, elem27 := range m.DirAddrs {
				elemTarget26, err := listTarget25.StartElem(i)
				if err != nil {
					return err
				}
				if err := elemTarget26.FromString(string(elem27), tt.NonOptional().Field(4).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget25.FinishElem(elemTarget26); err != nil {
					return err
				}
			}
			if err := fieldTarget23.FinishList(listTarget25); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget22, fieldTarget23); err != nil {
				return err
			}
		}
	}
	var30 := (m.Status == AdStatus(0))
	if var30 {
		if err := fieldsTarget1.ZeroField("Status"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget28, fieldTarget29, err := fieldsTarget1.StartField("Status")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Status.FillVDLTarget(fieldTarget29, tt.NonOptional().Field(5).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget28, fieldTarget29); err != nil {
				return err
			}
		}
	}
	var33 := (m.Lost == false)
	if var33 {
		if err := fieldsTarget1.ZeroField("Lost"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget31, fieldTarget32, err := fieldsTarget1.StartField("Lost")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget32.FromBool(bool(m.Lost), tt.NonOptional().Field(6).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget31, fieldTarget32); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *AdInfo) MakeVDLTarget() vdl.Target {
	return &AdInfoTarget{Value: m}
}

type AdInfoTarget struct {
	Value                     *AdInfo
	adTarget                  discovery.AdvertisementTarget
	encryptionAlgorithmTarget EncryptionAlgorithmTarget
	encryptionKeysTarget      __VDLTarget1_list
	hashTarget                AdHashTarget
	dirAddrsTarget            vdl.StringSliceTarget
	statusTarget              AdStatusTarget
	lostTarget                vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *AdInfoTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*AdInfo)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *AdInfoTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Ad":
		t.adTarget.Value = &t.Value.Ad
		target, err := &t.adTarget, error(nil)
		return nil, target, err
	case "EncryptionAlgorithm":
		t.encryptionAlgorithmTarget.Value = &t.Value.EncryptionAlgorithm
		target, err := &t.encryptionAlgorithmTarget, error(nil)
		return nil, target, err
	case "EncryptionKeys":
		t.encryptionKeysTarget.Value = &t.Value.EncryptionKeys
		target, err := &t.encryptionKeysTarget, error(nil)
		return nil, target, err
	case "Hash":
		t.hashTarget.Value = &t.Value.Hash
		target, err := &t.hashTarget, error(nil)
		return nil, target, err
	case "DirAddrs":
		t.dirAddrsTarget.Value = &t.Value.DirAddrs
		target, err := &t.dirAddrsTarget, error(nil)
		return nil, target, err
	case "Status":
		t.statusTarget.Value = &t.Value.Status
		target, err := &t.statusTarget, error(nil)
		return nil, target, err
	case "Lost":
		t.lostTarget.Value = &t.Value.Lost
		target, err := &t.lostTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/ref/lib/discovery.AdInfo", name)
	}
}
func (t *AdInfoTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *AdInfoTarget) ZeroField(name string) error {
	switch name {
	case "Ad":
		t.Value.Ad = discovery.Advertisement{}
		return nil
	case "EncryptionAlgorithm":
		t.Value.EncryptionAlgorithm = EncryptionAlgorithm(0)
		return nil
	case "EncryptionKeys":
		t.Value.EncryptionKeys = []EncryptionKey(nil)
		return nil
	case "Hash":
		t.Value.Hash = AdHash{}
		return nil
	case "DirAddrs":
		t.Value.DirAddrs = []string(nil)
		return nil
	case "Status":
		t.Value.Status = AdStatus(0)
		return nil
	case "Lost":
		t.Value.Lost = false
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/x/ref/lib/discovery.AdInfo", name)
	}
}
func (t *AdInfoTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// []EncryptionKey
type __VDLTarget1_list struct {
	Value      *[]EncryptionKey
	elemTarget EncryptionKeyTarget
	vdl.TargetBase
	vdl.ListTargetBase
}

func (t *__VDLTarget1_list) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {

	if ttWant := vdl.TypeOf((*[]EncryptionKey)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([]EncryptionKey, len)
	} else {
		*t.Value = (*t.Value)[:len]
	}
	return t, nil
}
func (t *__VDLTarget1_list) StartElem(index int) (elem vdl.Target, _ error) {
	t.elemTarget.Value = &(*t.Value)[index]
	target, err := &t.elemTarget, error(nil)
	return target, err
}
func (t *__VDLTarget1_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget1_list) FinishList(elem vdl.ListTarget) error {

	return nil
}

func (x *AdInfo) VDLRead(dec vdl.Decoder) error {
	*x = AdInfo{}
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	match := 0
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			if match == 0 && dec.Type().NumField() > 0 {
				return fmt.Errorf("no matching fields in struct %T, from %v", *x, dec.Type())
			}
			return dec.FinishValue()
		case "Ad":
			match++
			if err = x.Ad.VDLRead(dec); err != nil {
				return err
			}
		case "EncryptionAlgorithm":
			match++
			if err = x.EncryptionAlgorithm.VDLRead(dec); err != nil {
				return err
			}
		case "EncryptionKeys":
			match++
			if err = __VDLRead1_list(dec, &x.EncryptionKeys); err != nil {
				return err
			}
		case "Hash":
			match++
			if err = x.Hash.VDLRead(dec); err != nil {
				return err
			}
		case "DirAddrs":
			match++
			if err = __VDLRead2_list(dec, &x.DirAddrs); err != nil {
				return err
			}
		case "Status":
			match++
			if err = x.Status.VDLRead(dec); err != nil {
				return err
			}
		case "Lost":
			match++
			if err = dec.StartValue(); err != nil {
				return err
			}
			if x.Lost, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err = dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err = dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLRead1_list(dec vdl.Decoder, x *[]EncryptionKey) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len == 0:
		*x = nil
	case len > 0:
		*x = make([]EncryptionKey, 0, len)
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem EncryptionKey
		if err = elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

func __VDLRead2_list(dec vdl.Decoder, x *[]string) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len == 0:
		*x = nil
	case len > 0:
		*x = make([]string, 0, len)
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem string
		if err = dec.StartValue(); err != nil {
			return err
		}
		if elem, err = dec.DecodeString(); err != nil {
			return err
		}
		if err = dec.FinishValue(); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

//////////////////////////////////////////////////
// Const definitions

const NoEncryption = EncryptionAlgorithm(0)
const TestEncryption = EncryptionAlgorithm(1)
const IbeEncryption = EncryptionAlgorithm(2)
const AdReady = AdStatus(0)          // All information is available
const AdNotReady = AdStatus(1)       // Not all information is available for querying against it
const AdPartiallyReady = AdStatus(2) // All information except attachments is available

//////////////////////////////////////////////////
// Error definitions
var (
	ErrAdvertisementNotFound  = verror.Register("v.io/x/ref/lib/discovery.AdvertisementNotFound", verror.NoRetry, "{1:}{2:} advertisement not found: {3}")
	ErrAlreadyBeingAdvertised = verror.Register("v.io/x/ref/lib/discovery.AlreadyBeingAdvertised", verror.NoRetry, "{1:}{2:} already being advertised: {3}")
	ErrBadAdvertisement       = verror.Register("v.io/x/ref/lib/discovery.BadAdvertisement", verror.NoRetry, "{1:}{2:} invalid advertisement: {3}")
	ErrBadQuery               = verror.Register("v.io/x/ref/lib/discovery.BadQuery", verror.NoRetry, "{1:}{2:} invalid query: {3}")
	ErrDiscoveryClosed        = verror.Register("v.io/x/ref/lib/discovery.DiscoveryClosed", verror.NoRetry, "{1:}{2:} discovery closed")
	ErrNoDiscoveryPlugin      = verror.Register("v.io/x/ref/lib/discovery.NoDiscoveryPlugin", verror.NoRetry, "{1:}{2:} no discovery plugin")
)

// NewErrAdvertisementNotFound returns an error with the ErrAdvertisementNotFound ID.
func NewErrAdvertisementNotFound(ctx *context.T, id discovery.AdId) error {
	return verror.New(ErrAdvertisementNotFound, ctx, id)
}

// NewErrAlreadyBeingAdvertised returns an error with the ErrAlreadyBeingAdvertised ID.
func NewErrAlreadyBeingAdvertised(ctx *context.T, id discovery.AdId) error {
	return verror.New(ErrAlreadyBeingAdvertised, ctx, id)
}

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

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

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

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

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

// DirectoryClientMethods is the client interface
// containing Directory methods.
//
// Directory is the interface for advertisement directory service.
type DirectoryClientMethods interface {
	// Lookup returns the advertisement of the given service instance.
	//
	// The returned advertisement may not include all attachments.
	Lookup(_ *context.T, id discovery.AdId, _ ...rpc.CallOpt) (AdInfo, error)
	// GetAttachment returns the named attachment. Accessing non-existent attachment
	// is not an error - nil data is returned if not found.
	//
	// TODO(jhahn): Consider to return an error if not found.
	GetAttachment(_ *context.T, id discovery.AdId, name string, _ ...rpc.CallOpt) ([]byte, error)
}

// DirectoryClientStub adds universal methods to DirectoryClientMethods.
type DirectoryClientStub interface {
	DirectoryClientMethods
	rpc.UniversalServiceMethods
}

// DirectoryClient returns a client stub for Directory.
func DirectoryClient(name string) DirectoryClientStub {
	return implDirectoryClientStub{name}
}

type implDirectoryClientStub struct {
	name string
}

func (c implDirectoryClientStub) Lookup(ctx *context.T, i0 discovery.AdId, opts ...rpc.CallOpt) (o0 AdInfo, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Lookup", []interface{}{i0}, []interface{}{&o0}, opts...)
	return
}

func (c implDirectoryClientStub) GetAttachment(ctx *context.T, i0 discovery.AdId, i1 string, opts ...rpc.CallOpt) (o0 []byte, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetAttachment", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
	return
}

// DirectoryServerMethods is the interface a server writer
// implements for Directory.
//
// Directory is the interface for advertisement directory service.
type DirectoryServerMethods interface {
	// Lookup returns the advertisement of the given service instance.
	//
	// The returned advertisement may not include all attachments.
	Lookup(_ *context.T, _ rpc.ServerCall, id discovery.AdId) (AdInfo, error)
	// GetAttachment returns the named attachment. Accessing non-existent attachment
	// is not an error - nil data is returned if not found.
	//
	// TODO(jhahn): Consider to return an error if not found.
	GetAttachment(_ *context.T, _ rpc.ServerCall, id discovery.AdId, name string) ([]byte, error)
}

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

// DirectoryServerStub adds universal methods to DirectoryServerStubMethods.
type DirectoryServerStub interface {
	DirectoryServerStubMethods
	// Describe the Directory interfaces.
	Describe__() []rpc.InterfaceDesc
}

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

func (s implDirectoryServerStub) Lookup(ctx *context.T, call rpc.ServerCall, i0 discovery.AdId) (AdInfo, error) {
	return s.impl.Lookup(ctx, call, i0)
}

func (s implDirectoryServerStub) GetAttachment(ctx *context.T, call rpc.ServerCall, i0 discovery.AdId, i1 string) ([]byte, error) {
	return s.impl.GetAttachment(ctx, call, i0, i1)
}

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

func (s implDirectoryServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{DirectoryDesc}
}

// DirectoryDesc describes the Directory interface.
var DirectoryDesc rpc.InterfaceDesc = descDirectory

// descDirectory hides the desc to keep godoc clean.
var descDirectory = rpc.InterfaceDesc{
	Name:    "Directory",
	PkgPath: "v.io/x/ref/lib/discovery",
	Doc:     "// Directory is the interface for advertisement directory service.",
	Methods: []rpc.MethodDesc{
		{
			Name: "Lookup",
			Doc:  "// Lookup returns the advertisement of the given service instance.\n//\n// The returned advertisement may not include all attachments.",
			InArgs: []rpc.ArgDesc{
				{"id", ``}, // discovery.AdId
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // AdInfo
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "GetAttachment",
			Doc:  "// GetAttachment returns the named attachment. Accessing non-existent attachment\n// is not an error - nil data is returned if not found.\n//\n// TODO(jhahn): Consider to return an error if not found.",
			InArgs: []rpc.ArgDesc{
				{"id", ``},   // discovery.AdId
				{"name", ``}, // string
			},
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []byte
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

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((*Uuid)(nil))
	vdl.Register((*EncryptionAlgorithm)(nil))
	vdl.Register((*EncryptionKey)(nil))
	vdl.Register((*AdStatus)(nil))
	vdl.Register((*AdHash)(nil))
	vdl.Register((*AdInfo)(nil))

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrAdvertisementNotFound.ID), "{1:}{2:} advertisement not found: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrAlreadyBeingAdvertised.ID), "{1:}{2:} already being advertised: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBadAdvertisement.ID), "{1:}{2:} invalid advertisement: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBadQuery.ID), "{1:}{2:} invalid query: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrDiscoveryClosed.ID), "{1:}{2:} discovery closed")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoDiscoveryPlugin.ID), "{1:}{2:} no discovery plugin")

	return struct{}{}
}
