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

package security

import (
	"fmt"
	"reflect"
	"time"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/uniqueid"
	"v.io/v23/vdl"
	vdltime "v.io/v23/vdlroot/time"
	"v.io/v23/verror"
	"v.io/v23/vom"
)

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

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

type nonce [16]byte

func (nonce) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.nonce"`
}) {
}

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

func (m *nonce) MakeVDLTarget() vdl.Target {
	return &nonceTarget{Value: m}
}

type nonceTarget struct {
	Value *nonce
	vdl.TargetBase
}

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

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

	return nil
}

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

func (x nonce) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*nonce)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeBytes([]byte(x[:])); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

// Caveat is a condition on the validity of a blessing/discharge.
//
// These conditions are provided when asking a principal to create
// a blessing/discharge and are verified when extracting blessings
// (Blessings.ForName in the Go API).
//
// Given a Hash, the message digest of a caveat is:
// Hash(Hash(Id), Hash(ParamVom))
type Caveat struct {
	Id       uniqueid.Id // The identifier of the caveat validation function.
	ParamVom []byte      // VOM-encoded bytes of the parameters to be provided to the validation function.
}

func (Caveat) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.Caveat"`
}) {
}

func (m *Caveat) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Id == uniqueid.Id{})
	if var4 {
		if err := fieldsTarget1.ZeroField("Id"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Id")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Id.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var7 bool
	if len(m.ParamVom) == 0 {
		var7 = true
	}
	if var7 {
		if err := fieldsTarget1.ZeroField("ParamVom"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("ParamVom")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := fieldTarget6.FromBytes([]byte(m.ParamVom), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Caveat) MakeVDLTarget() vdl.Target {
	return &CaveatTarget{Value: m}
}

type CaveatTarget struct {
	Value          *Caveat
	idTarget       uniqueid.IdTarget
	paramVomTarget vdl.BytesTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*Caveat)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *CaveatTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Id":
		t.idTarget.Value = &t.Value.Id
		target, err := &t.idTarget, error(nil)
		return nil, target, err
	case "ParamVom":
		t.paramVomTarget.Value = &t.Value.ParamVom
		target, err := &t.paramVomTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *CaveatTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *CaveatTarget) ZeroField(name string) error {
	switch name {
	case "Id":
		t.Value.Id = uniqueid.Id{}
		return nil
	case "ParamVom":
		t.Value.ParamVom = []byte(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *CaveatTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x Caveat) VDLIsZero() bool {
	if x.Id != (uniqueid.Id{}) {
		return false
	}
	if len(x.ParamVom) != 0 {
		return false
	}
	return true
}

func (x Caveat) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Caveat)(nil)).Elem()); err != nil {
		return err
	}
	if x.Id != (uniqueid.Id{}) {
		if err := enc.NextField("Id"); err != nil {
			return err
		}
		if err := x.Id.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.ParamVom) != 0 {
		if err := enc.NextField("ParamVom"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*[]byte)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeBytes(x.ParamVom); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Caveat) VDLRead(dec vdl.Decoder) error {
	*x = Caveat{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Id":
			if err := x.Id.VDLRead(dec); err != nil {
				return err
			}
		case "ParamVom":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if err := dec.DecodeBytes(-1, &x.ParamVom); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// ThirdPartyRequirements specifies the information required by the third-party
// that will issue discharges for third-party caveats.
//
// These requirements are typically used to construct a DischargeImpetus, which
// will be sent to the third-party.
type ThirdPartyRequirements struct {
	ReportServer    bool // The blessings presented by the server of an IPC call.
	ReportMethod    bool // The name of the method being invoked.
	ReportArguments bool // Arguments to the method being invoked.
}

func (ThirdPartyRequirements) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.ThirdPartyRequirements"`
}) {
}

func (m *ThirdPartyRequirements) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.ReportServer == false)
	if var4 {
		if err := fieldsTarget1.ZeroField("ReportServer"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("ReportServer")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromBool(bool(m.ReportServer), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.ReportMethod == false)
	if var7 {
		if err := fieldsTarget1.ZeroField("ReportMethod"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("ReportMethod")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromBool(bool(m.ReportMethod), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.ReportArguments == false)
	if var10 {
		if err := fieldsTarget1.ZeroField("ReportArguments"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("ReportArguments")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget9.FromBool(bool(m.ReportArguments), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *ThirdPartyRequirements) MakeVDLTarget() vdl.Target {
	return &ThirdPartyRequirementsTarget{Value: m}
}

type ThirdPartyRequirementsTarget struct {
	Value                 *ThirdPartyRequirements
	reportServerTarget    vdl.BoolTarget
	reportMethodTarget    vdl.BoolTarget
	reportArgumentsTarget vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*ThirdPartyRequirements)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *ThirdPartyRequirementsTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "ReportServer":
		t.reportServerTarget.Value = &t.Value.ReportServer
		target, err := &t.reportServerTarget, error(nil)
		return nil, target, err
	case "ReportMethod":
		t.reportMethodTarget.Value = &t.Value.ReportMethod
		target, err := &t.reportMethodTarget, error(nil)
		return nil, target, err
	case "ReportArguments":
		t.reportArgumentsTarget.Value = &t.Value.ReportArguments
		target, err := &t.reportArgumentsTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *ThirdPartyRequirementsTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *ThirdPartyRequirementsTarget) ZeroField(name string) error {
	switch name {
	case "ReportServer":
		t.Value.ReportServer = false
		return nil
	case "ReportMethod":
		t.Value.ReportMethod = false
		return nil
	case "ReportArguments":
		t.Value.ReportArguments = false
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *ThirdPartyRequirementsTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x ThirdPartyRequirements) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ThirdPartyRequirements)(nil)).Elem()); err != nil {
		return err
	}
	if x.ReportServer {
		if err := enc.NextField("ReportServer"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.ReportServer); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.ReportMethod {
		if err := enc.NextField("ReportMethod"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.ReportMethod); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.ReportArguments {
		if err := enc.NextField("ReportArguments"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.ReportArguments); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ThirdPartyRequirements) VDLRead(dec vdl.Decoder) error {
	*x = ThirdPartyRequirements{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "ReportServer":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.ReportServer, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "ReportMethod":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.ReportMethod, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "ReportArguments":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.ReportArguments, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// publicKeyThirdPartyCaveatParam represents a third-party caveat that requires
// PublicKeyDischarge(s) to be issued by a principal identified by a public key.
//
// The Id of the caveat is base64-encoded:
// hash(hash(Nonce), hash(DischargerKey), hash(Caveats[0]), hash(Caveats[1]), ...)
// where hash is a cryptographic hash function with a security strength
// equivalent to that of the DischargerKey. For example, if DischargerKey
// represents an ECDSA public key with the P384 curve, then hash should be
// SHA384.
type publicKeyThirdPartyCaveatParam struct {
	// Nonce specifies a cryptographically random nonce associated with an
	// instance of the caveat. This prevents discharge replays, where
	// discharges for ThirdPartyCaveats embedded in the certificates for
	// one blessing can be used for another blessing.
	//
	// Whether discharge re-use is a desired or un-desired property is
	// still under debate. Till the debate is settled, we err on the side
	// of discouraging re-use.
	Nonce nonce
	// Caveats specifies the caveats that have to be validated
	// before minting a discharge for a publicKeyCaveat.
	Caveats []Caveat
	// DER-encoded PKIX public key of the principal that can issue discharges.
	DischargerKey []byte
	// Object name where the third-party that can issue discharges can be found.
	DischargerLocation string
	// Information required by the third-party in order to issue a discharge.
	DischargerRequirements ThirdPartyRequirements
}

func (publicKeyThirdPartyCaveatParam) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.publicKeyThirdPartyCaveatParam"`
}) {
}

func (m *publicKeyThirdPartyCaveatParam) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Nonce == nonce{})
	if var4 {
		if err := fieldsTarget1.ZeroField("Nonce"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Nonce")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Nonce.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var7 bool
	if len(m.Caveats) == 0 {
		var7 = true
	}
	if var7 {
		if err := fieldsTarget1.ZeroField("Caveats"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Caveats")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget8, err := fieldTarget6.StartList(tt.NonOptional().Field(1).Type, len(m.Caveats))
			if err != nil {
				return err
			}
			for i, elem10 := range m.Caveats {
				elemTarget9, err := listTarget8.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem10.FillVDLTarget(elemTarget9, tt.NonOptional().Field(1).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget8.FinishElem(elemTarget9); err != nil {
					return err
				}
			}
			if err := fieldTarget6.FinishList(listTarget8); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var var13 bool
	if len(m.DischargerKey) == 0 {
		var13 = true
	}
	if var13 {
		if err := fieldsTarget1.ZeroField("DischargerKey"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("DischargerKey")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := fieldTarget12.FromBytes([]byte(m.DischargerKey), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	var16 := (m.DischargerLocation == "")
	if var16 {
		if err := fieldsTarget1.ZeroField("DischargerLocation"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget14, fieldTarget15, err := fieldsTarget1.StartField("DischargerLocation")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget15.FromString(string(m.DischargerLocation), tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget14, fieldTarget15); err != nil {
				return err
			}
		}
	}
	var19 := (m.DischargerRequirements == ThirdPartyRequirements{})
	if var19 {
		if err := fieldsTarget1.ZeroField("DischargerRequirements"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget17, fieldTarget18, err := fieldsTarget1.StartField("DischargerRequirements")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.DischargerRequirements.FillVDLTarget(fieldTarget18, tt.NonOptional().Field(4).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget17, fieldTarget18); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *publicKeyThirdPartyCaveatParam) MakeVDLTarget() vdl.Target {
	return &publicKeyThirdPartyCaveatParamTarget{Value: m}
}

type publicKeyThirdPartyCaveatParamTarget struct {
	Value                        *publicKeyThirdPartyCaveatParam
	nonceTarget                  nonceTarget
	caveatsTarget                __VDLTarget1_list
	dischargerKeyTarget          vdl.BytesTarget
	dischargerLocationTarget     vdl.StringTarget
	dischargerRequirementsTarget ThirdPartyRequirementsTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*publicKeyThirdPartyCaveatParam)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *publicKeyThirdPartyCaveatParamTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Nonce":
		t.nonceTarget.Value = &t.Value.Nonce
		target, err := &t.nonceTarget, error(nil)
		return nil, target, err
	case "Caveats":
		t.caveatsTarget.Value = &t.Value.Caveats
		target, err := &t.caveatsTarget, error(nil)
		return nil, target, err
	case "DischargerKey":
		t.dischargerKeyTarget.Value = &t.Value.DischargerKey
		target, err := &t.dischargerKeyTarget, error(nil)
		return nil, target, err
	case "DischargerLocation":
		t.dischargerLocationTarget.Value = &t.Value.DischargerLocation
		target, err := &t.dischargerLocationTarget, error(nil)
		return nil, target, err
	case "DischargerRequirements":
		t.dischargerRequirementsTarget.Value = &t.Value.DischargerRequirements
		target, err := &t.dischargerRequirementsTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *publicKeyThirdPartyCaveatParamTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *publicKeyThirdPartyCaveatParamTarget) ZeroField(name string) error {
	switch name {
	case "Nonce":
		t.Value.Nonce = nonce{}
		return nil
	case "Caveats":
		t.Value.Caveats = []Caveat(nil)
		return nil
	case "DischargerKey":
		t.Value.DischargerKey = []byte(nil)
		return nil
	case "DischargerLocation":
		t.Value.DischargerLocation = ""
		return nil
	case "DischargerRequirements":
		t.Value.DischargerRequirements = ThirdPartyRequirements{}
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *publicKeyThirdPartyCaveatParamTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// []Caveat
type __VDLTarget1_list struct {
	Value      *[]Caveat
	elemTarget CaveatTarget
	vdl.TargetBase
	vdl.ListTargetBase
}

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

	if ttWant := vdl.TypeOf((*[]Caveat)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([]Caveat, 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 publicKeyThirdPartyCaveatParam) VDLIsZero() bool {
	if x.Nonce != (nonce{}) {
		return false
	}
	if len(x.Caveats) != 0 {
		return false
	}
	if len(x.DischargerKey) != 0 {
		return false
	}
	if x.DischargerLocation != "" {
		return false
	}
	if x.DischargerRequirements != (ThirdPartyRequirements{}) {
		return false
	}
	return true
}

func (x publicKeyThirdPartyCaveatParam) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*publicKeyThirdPartyCaveatParam)(nil)).Elem()); err != nil {
		return err
	}
	if x.Nonce != (nonce{}) {
		if err := enc.NextField("Nonce"); err != nil {
			return err
		}
		if err := x.Nonce.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.Caveats) != 0 {
		if err := enc.NextField("Caveats"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Caveats); err != nil {
			return err
		}
	}
	if len(x.DischargerKey) != 0 {
		if err := enc.NextField("DischargerKey"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*[]byte)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeBytes(x.DischargerKey); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.DischargerLocation != "" {
		if err := enc.NextField("DischargerLocation"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.DischargerLocation); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.DischargerRequirements != (ThirdPartyRequirements{}) {
		if err := enc.NextField("DischargerRequirements"); err != nil {
			return err
		}
		if err := x.DischargerRequirements.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []Caveat) error {
	if err := enc.StartValue(vdl.TypeOf((*[]Caveat)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := x[i].VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *publicKeyThirdPartyCaveatParam) VDLRead(dec vdl.Decoder) error {
	*x = publicKeyThirdPartyCaveatParam{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Nonce":
			if err := x.Nonce.VDLRead(dec); err != nil {
				return err
			}
		case "Caveats":
			if err := __VDLReadAnon_list_1(dec, &x.Caveats); err != nil {
				return err
			}
		case "DischargerKey":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if err := dec.DecodeBytes(-1, &x.DischargerKey); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "DischargerLocation":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.DischargerLocation, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "DischargerRequirements":
			if err := x.DischargerRequirements.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]Caveat) 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 = make([]Caveat, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem Caveat
		if err := elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

// Hash identifies a cryptographic hash function approved for use in signature algorithms.
type Hash string

func (Hash) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.Hash"`
}) {
}

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

func (m *Hash) MakeVDLTarget() vdl.Target {
	return &HashTarget{Value: m}
}

type HashTarget struct {
	Value *Hash
	vdl.TargetBase
}

func (t *HashTarget) FromString(src string, tt *vdl.Type) error {

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

	return nil
}

func (x Hash) VDLIsZero() bool {
	return x == ""
}

func (x Hash) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Hash)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(string(x)); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

// Signature represents a digital signature.
type Signature struct {
	// Purpose of the signature. Can be used to prevent type attacks.
	// (See Section 4.2 of http://www-users.cs.york.ac.uk/~jac/PublishedPapers/reviewV1_1997.pdf for example).
	// The actual signature (R, S values for ECDSA keys) is produced by signing: Hash(Hash(message), Hash(Purpose)).
	Purpose []byte
	// Cryptographic hash function applied to the message before computing the signature.
	Hash Hash
	// Pair of integers that make up an ECDSA signature.
	R []byte
	S []byte
}

func (Signature) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.Signature"`
}) {
}

func (m *Signature) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.Purpose) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("Purpose"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Purpose")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := fieldTarget3.FromBytes([]byte(m.Purpose), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Hash == Hash(""))
	if var7 {
		if err := fieldsTarget1.ZeroField("Hash"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Hash")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Hash.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var var10 bool
	if len(m.R) == 0 {
		var10 = true
	}
	if var10 {
		if err := fieldsTarget1.ZeroField("R"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("R")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := fieldTarget9.FromBytes([]byte(m.R), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var var13 bool
	if len(m.S) == 0 {
		var13 = true
	}
	if var13 {
		if err := fieldsTarget1.ZeroField("S"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("S")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := fieldTarget12.FromBytes([]byte(m.S), tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Signature) MakeVDLTarget() vdl.Target {
	return &SignatureTarget{Value: m}
}

type SignatureTarget struct {
	Value         *Signature
	purposeTarget vdl.BytesTarget
	hashTarget    HashTarget
	rTarget       vdl.BytesTarget
	sTarget       vdl.BytesTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*Signature)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *SignatureTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Purpose":
		t.purposeTarget.Value = &t.Value.Purpose
		target, err := &t.purposeTarget, 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 "R":
		t.rTarget.Value = &t.Value.R
		target, err := &t.rTarget, error(nil)
		return nil, target, err
	case "S":
		t.sTarget.Value = &t.Value.S
		target, err := &t.sTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *SignatureTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *SignatureTarget) ZeroField(name string) error {
	switch name {
	case "Purpose":
		t.Value.Purpose = []byte(nil)
		return nil
	case "Hash":
		t.Value.Hash = Hash("")
		return nil
	case "R":
		t.Value.R = []byte(nil)
		return nil
	case "S":
		t.Value.S = []byte(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *SignatureTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x Signature) VDLIsZero() bool {
	if len(x.Purpose) != 0 {
		return false
	}
	if x.Hash != "" {
		return false
	}
	if len(x.R) != 0 {
		return false
	}
	if len(x.S) != 0 {
		return false
	}
	return true
}

func (x Signature) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Signature)(nil)).Elem()); err != nil {
		return err
	}
	if len(x.Purpose) != 0 {
		if err := enc.NextField("Purpose"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*[]byte)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeBytes(x.Purpose); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Hash != "" {
		if err := enc.NextField("Hash"); err != nil {
			return err
		}
		if err := x.Hash.VDLWrite(enc); err != nil {
			return err
		}
	}
	if len(x.R) != 0 {
		if err := enc.NextField("R"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*[]byte)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeBytes(x.R); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.S) != 0 {
		if err := enc.NextField("S"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*[]byte)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeBytes(x.S); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Signature) VDLRead(dec vdl.Decoder) error {
	*x = Signature{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Purpose":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if err := dec.DecodeBytes(-1, &x.Purpose); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Hash":
			if err := x.Hash.VDLRead(dec); err != nil {
				return err
			}
		case "R":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if err := dec.DecodeBytes(-1, &x.R); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "S":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if err := dec.DecodeBytes(-1, &x.S); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// PublicKeyDischarge represents a discharge for third party caveats that
// require a signature from a third-party's public key.
//
// The message digest of this structure is computed as follows:
// hash(hash(ThirdPartyCaveatId), hash(Caveats[0]), hash(Caveats[1]), ...),
// where hash is a cryptographic hash function with a security strength
// equivalent to the strength of the public key of the principal issuing the
// discharge.
type PublicKeyDischarge struct {
	ThirdPartyCaveatId string    // Id of the third party caveat for which this discharge was issued.
	Caveats            []Caveat  // Caveats on the use of this discharge.
	Signature          Signature // Signature of the content hash of this discharge by the discharger.
}

func (PublicKeyDischarge) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.PublicKeyDischarge"`
}) {
}

func (m *PublicKeyDischarge) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.ThirdPartyCaveatId == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("ThirdPartyCaveatId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("ThirdPartyCaveatId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.ThirdPartyCaveatId), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var7 bool
	if len(m.Caveats) == 0 {
		var7 = true
	}
	if var7 {
		if err := fieldsTarget1.ZeroField("Caveats"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Caveats")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget8, err := fieldTarget6.StartList(tt.NonOptional().Field(1).Type, len(m.Caveats))
			if err != nil {
				return err
			}
			for i, elem10 := range m.Caveats {
				elemTarget9, err := listTarget8.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem10.FillVDLTarget(elemTarget9, tt.NonOptional().Field(1).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget8.FinishElem(elemTarget9); err != nil {
					return err
				}
			}
			if err := fieldTarget6.FinishList(listTarget8); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var13 := true
	var var14 bool
	if len(m.Signature.Purpose) == 0 {
		var14 = true
	}
	var13 = var13 && var14
	var15 := (m.Signature.Hash == Hash(""))
	var13 = var13 && var15
	var var16 bool
	if len(m.Signature.R) == 0 {
		var16 = true
	}
	var13 = var13 && var16
	var var17 bool
	if len(m.Signature.S) == 0 {
		var17 = true
	}
	var13 = var13 && var17
	if var13 {
		if err := fieldsTarget1.ZeroField("Signature"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("Signature")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Signature.FillVDLTarget(fieldTarget12, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *PublicKeyDischarge) MakeVDLTarget() vdl.Target {
	return &PublicKeyDischargeTarget{Value: m}
}

type PublicKeyDischargeTarget struct {
	Value                    *PublicKeyDischarge
	thirdPartyCaveatIdTarget vdl.StringTarget
	caveatsTarget            __VDLTarget1_list
	signatureTarget          SignatureTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*PublicKeyDischarge)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *PublicKeyDischargeTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "ThirdPartyCaveatId":
		t.thirdPartyCaveatIdTarget.Value = &t.Value.ThirdPartyCaveatId
		target, err := &t.thirdPartyCaveatIdTarget, error(nil)
		return nil, target, err
	case "Caveats":
		t.caveatsTarget.Value = &t.Value.Caveats
		target, err := &t.caveatsTarget, error(nil)
		return nil, target, err
	case "Signature":
		t.signatureTarget.Value = &t.Value.Signature
		target, err := &t.signatureTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *PublicKeyDischargeTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *PublicKeyDischargeTarget) ZeroField(name string) error {
	switch name {
	case "ThirdPartyCaveatId":
		t.Value.ThirdPartyCaveatId = ""
		return nil
	case "Caveats":
		t.Value.Caveats = []Caveat(nil)
		return nil
	case "Signature":
		t.Value.Signature = Signature{}
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *PublicKeyDischargeTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x PublicKeyDischarge) VDLIsZero() bool {
	if x.ThirdPartyCaveatId != "" {
		return false
	}
	if len(x.Caveats) != 0 {
		return false
	}
	if !x.Signature.VDLIsZero() {
		return false
	}
	return true
}

func (x PublicKeyDischarge) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*PublicKeyDischarge)(nil)).Elem()); err != nil {
		return err
	}
	if x.ThirdPartyCaveatId != "" {
		if err := enc.NextField("ThirdPartyCaveatId"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.ThirdPartyCaveatId); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.Caveats) != 0 {
		if err := enc.NextField("Caveats"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Caveats); err != nil {
			return err
		}
	}
	if !x.Signature.VDLIsZero() {
		if err := enc.NextField("Signature"); err != nil {
			return err
		}
		if err := x.Signature.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *PublicKeyDischarge) VDLRead(dec vdl.Decoder) error {
	*x = PublicKeyDischarge{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "ThirdPartyCaveatId":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.ThirdPartyCaveatId, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Caveats":
			if err := __VDLReadAnon_list_1(dec, &x.Caveats); err != nil {
				return err
			}
		case "Signature":
			if err := x.Signature.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// BlessingPattern is a pattern that is matched by specific blessings.
//
// A pattern can either be a blessing (slash-separated human-readable string)
// or a blessing ending in "/$". A pattern ending in "/$" is matched exactly
// by the blessing specified by the pattern string with the "/$" suffix stripped
// out. For example, the pattern "a/b/c/$" is matched by exactly by the blessing
// "a/b/c".
//
// A pattern not ending in "/$" is more permissive, and is also matched by blessings
// that are extensions of the pattern (including the pattern itself). For example, the
// pattern "a/b/c" is matched by the blessings "a/b/c", "a/b/c/x", "a/b/c/x/y", etc.
//
// TODO(ataly, ashankar): Define a formal BNF grammar for blessings and blessing patterns.
type BlessingPattern string

func (BlessingPattern) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.BlessingPattern"`
}) {
}

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

func (m *BlessingPattern) MakeVDLTarget() vdl.Target {
	return &BlessingPatternTarget{Value: m}
}

type BlessingPatternTarget struct {
	Value *BlessingPattern
	vdl.TargetBase
}

func (t *BlessingPatternTarget) FromString(src string, tt *vdl.Type) error {

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

	return nil
}

func (x BlessingPattern) VDLIsZero() bool {
	return x == ""
}

func (x BlessingPattern) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*BlessingPattern)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(string(x)); err != nil {
		return err
	}
	return enc.FinishValue()
}

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

// DischargeImpetus encapsulates the motivation for a discharge being sought.
//
// These values are reported by a principal that is requesting a Discharge for
// a third-party caveat on one of its blessings. The third-party issues
// discharges cannot safely assume that all these values are provided, or that
// they are provided honestly.
//
// Implementations of services that issue discharges are encouraged to add
// caveats to the discharge that bind the discharge to the impetus, thereby
// rendering the discharge unsuable for any other purpose.
type DischargeImpetus struct {
	Server    []BlessingPattern // The client intends to use the discharge to communicate with a server that has a blessing matching one of the patterns in this set.
	Method    string            // Name of the method being invoked by the client.
	Arguments []*vom.RawBytes   // Arguments to the method invocation.
}

func (DischargeImpetus) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.DischargeImpetus"`
}) {
}

func (m *DischargeImpetus) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.Server) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("Server"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Server")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget5, err := fieldTarget3.StartList(tt.NonOptional().Field(0).Type, len(m.Server))
			if err != nil {
				return err
			}
			for i, elem7 := range m.Server {
				elemTarget6, err := listTarget5.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem7.FillVDLTarget(elemTarget6, tt.NonOptional().Field(0).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget5.FinishElem(elemTarget6); err != nil {
					return err
				}
			}
			if err := fieldTarget3.FinishList(listTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var10 := (m.Method == "")
	if var10 {
		if err := fieldsTarget1.ZeroField("Method"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Method")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget9.FromString(string(m.Method), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var var13 bool
	if len(m.Arguments) == 0 {
		var13 = true
	}
	if var13 {
		if err := fieldsTarget1.ZeroField("Arguments"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("Arguments")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget14, err := fieldTarget12.StartList(tt.NonOptional().Field(2).Type, len(m.Arguments))
			if err != nil {
				return err
			}
			for i, elem16 := range m.Arguments {
				elemTarget15, err := listTarget14.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem16.FillVDLTarget(elemTarget15, tt.NonOptional().Field(2).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget14.FinishElem(elemTarget15); err != nil {
					return err
				}
			}
			if err := fieldTarget12.FinishList(listTarget14); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *DischargeImpetus) MakeVDLTarget() vdl.Target {
	return &DischargeImpetusTarget{Value: m}
}

type DischargeImpetusTarget struct {
	Value           *DischargeImpetus
	serverTarget    __VDLTarget2_list
	methodTarget    vdl.StringTarget
	argumentsTarget __VDLTarget3_list
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*DischargeImpetus)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *DischargeImpetusTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Server":
		t.serverTarget.Value = &t.Value.Server
		target, err := &t.serverTarget, error(nil)
		return nil, target, err
	case "Method":
		t.methodTarget.Value = &t.Value.Method
		target, err := &t.methodTarget, error(nil)
		return nil, target, err
	case "Arguments":
		t.argumentsTarget.Value = &t.Value.Arguments
		target, err := &t.argumentsTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *DischargeImpetusTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *DischargeImpetusTarget) ZeroField(name string) error {
	switch name {
	case "Server":
		t.Value.Server = []BlessingPattern(nil)
		return nil
	case "Method":
		t.Value.Method = ""
		return nil
	case "Arguments":
		t.Value.Arguments = []*vom.RawBytes(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *DischargeImpetusTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

// []BlessingPattern
type __VDLTarget2_list struct {
	Value      *[]BlessingPattern
	elemTarget BlessingPatternTarget
	vdl.TargetBase
	vdl.ListTargetBase
}

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

	if ttWant := vdl.TypeOf((*[]BlessingPattern)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([]BlessingPattern, len)
	} else {
		*t.Value = (*t.Value)[:len]
	}
	return t, nil
}
func (t *__VDLTarget2_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 *__VDLTarget2_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget2_list) FinishList(elem vdl.ListTarget) error {

	return nil
}

// []*vom.RawBytes
type __VDLTarget3_list struct {
	Value *[]*vom.RawBytes

	vdl.TargetBase
	vdl.ListTargetBase
}

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

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

	return nil
}

func (x DischargeImpetus) VDLIsZero() bool {
	if len(x.Server) != 0 {
		return false
	}
	if x.Method != "" {
		return false
	}
	if len(x.Arguments) != 0 {
		return false
	}
	return true
}

func (x DischargeImpetus) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*DischargeImpetus)(nil)).Elem()); err != nil {
		return err
	}
	if len(x.Server) != 0 {
		if err := enc.NextField("Server"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.Server); err != nil {
			return err
		}
	}
	if x.Method != "" {
		if err := enc.NextField("Method"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Method); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.Arguments) != 0 {
		if err := enc.NextField("Arguments"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_3(enc, x.Arguments); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_2(enc vdl.Encoder, x []BlessingPattern) error {
	if err := enc.StartValue(vdl.TypeOf((*[]BlessingPattern)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := x[i].VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_3(enc vdl.Encoder, x []*vom.RawBytes) error {
	if err := enc.StartValue(vdl.TypeOf((*[]*vom.RawBytes)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if x[i] == nil {
			if err := enc.NilValue(vdl.AnyType); err != nil {
				return err
			}
		} else {
			if err := x[i].VDLWrite(enc); err != nil {
				return err
			}
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *DischargeImpetus) VDLRead(dec vdl.Decoder) error {
	*x = DischargeImpetus{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Server":
			if err := __VDLReadAnon_list_2(dec, &x.Server); err != nil {
				return err
			}
		case "Method":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Method, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Arguments":
			if err := __VDLReadAnon_list_3(dec, &x.Arguments); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_2(dec vdl.Decoder, x *[]BlessingPattern) 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 = make([]BlessingPattern, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem BlessingPattern
		if err := elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

func __VDLReadAnon_list_3(dec vdl.Decoder, x *[]*vom.RawBytes) 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 = make([]*vom.RawBytes, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem *vom.RawBytes
		if err := elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

// Certificate represents the cryptographic proof of the binding of
// extensions of a blessing held by one principal to another (represented by
// a public key) under specific caveats.
//
// For example, if a principal P1 has a blessing "alice", then it can
// extend it with a Certificate to generate the blessing "alice/friend" for
// another principal P2.
type Certificate struct {
	Extension string    // Human-readable string extension bound to PublicKey.
	PublicKey []byte    // DER-encoded PKIX public key.
	Caveats   []Caveat  // Caveats on the binding of Name to PublicKey.
	Signature Signature // Signature by the blessing principal that binds the extension to the public key.
}

func (Certificate) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.Certificate"`
}) {
}

func (m *Certificate) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Extension == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Extension"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Extension")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Extension), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var7 bool
	if len(m.PublicKey) == 0 {
		var7 = true
	}
	if var7 {
		if err := fieldsTarget1.ZeroField("PublicKey"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("PublicKey")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := fieldTarget6.FromBytes([]byte(m.PublicKey), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var var10 bool
	if len(m.Caveats) == 0 {
		var10 = true
	}
	if var10 {
		if err := fieldsTarget1.ZeroField("Caveats"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Caveats")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget11, err := fieldTarget9.StartList(tt.NonOptional().Field(2).Type, len(m.Caveats))
			if err != nil {
				return err
			}
			for i, elem13 := range m.Caveats {
				elemTarget12, err := listTarget11.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem13.FillVDLTarget(elemTarget12, tt.NonOptional().Field(2).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget11.FinishElem(elemTarget12); err != nil {
					return err
				}
			}
			if err := fieldTarget9.FinishList(listTarget11); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var16 := true
	var var17 bool
	if len(m.Signature.Purpose) == 0 {
		var17 = true
	}
	var16 = var16 && var17
	var18 := (m.Signature.Hash == Hash(""))
	var16 = var16 && var18
	var var19 bool
	if len(m.Signature.R) == 0 {
		var19 = true
	}
	var16 = var16 && var19
	var var20 bool
	if len(m.Signature.S) == 0 {
		var20 = true
	}
	var16 = var16 && var20
	if var16 {
		if err := fieldsTarget1.ZeroField("Signature"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget14, fieldTarget15, err := fieldsTarget1.StartField("Signature")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Signature.FillVDLTarget(fieldTarget15, tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget14, fieldTarget15); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Certificate) MakeVDLTarget() vdl.Target {
	return &CertificateTarget{Value: m}
}

type CertificateTarget struct {
	Value           *Certificate
	extensionTarget vdl.StringTarget
	publicKeyTarget vdl.BytesTarget
	caveatsTarget   __VDLTarget1_list
	signatureTarget SignatureTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*Certificate)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *CertificateTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Extension":
		t.extensionTarget.Value = &t.Value.Extension
		target, err := &t.extensionTarget, error(nil)
		return nil, target, err
	case "PublicKey":
		t.publicKeyTarget.Value = &t.Value.PublicKey
		target, err := &t.publicKeyTarget, error(nil)
		return nil, target, err
	case "Caveats":
		t.caveatsTarget.Value = &t.Value.Caveats
		target, err := &t.caveatsTarget, error(nil)
		return nil, target, err
	case "Signature":
		t.signatureTarget.Value = &t.Value.Signature
		target, err := &t.signatureTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *CertificateTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *CertificateTarget) ZeroField(name string) error {
	switch name {
	case "Extension":
		t.Value.Extension = ""
		return nil
	case "PublicKey":
		t.Value.PublicKey = []byte(nil)
		return nil
	case "Caveats":
		t.Value.Caveats = []Caveat(nil)
		return nil
	case "Signature":
		t.Value.Signature = Signature{}
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *CertificateTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x Certificate) VDLIsZero() bool {
	if x.Extension != "" {
		return false
	}
	if len(x.PublicKey) != 0 {
		return false
	}
	if len(x.Caveats) != 0 {
		return false
	}
	if !x.Signature.VDLIsZero() {
		return false
	}
	return true
}

func (x Certificate) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Certificate)(nil)).Elem()); err != nil {
		return err
	}
	if x.Extension != "" {
		if err := enc.NextField("Extension"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Extension); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.PublicKey) != 0 {
		if err := enc.NextField("PublicKey"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*[]byte)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeBytes(x.PublicKey); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.Caveats) != 0 {
		if err := enc.NextField("Caveats"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Caveats); err != nil {
			return err
		}
	}
	if !x.Signature.VDLIsZero() {
		if err := enc.NextField("Signature"); err != nil {
			return err
		}
		if err := x.Signature.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Certificate) VDLRead(dec vdl.Decoder) error {
	*x = Certificate{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Extension":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Extension, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "PublicKey":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if err := dec.DecodeBytes(-1, &x.PublicKey); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Caveats":
			if err := __VDLReadAnon_list_1(dec, &x.Caveats); err != nil {
				return err
			}
		case "Signature":
			if err := x.Signature.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// CaveatDescriptor defines an association between a caveat validation function
// (addressed by globally unique identifier) and the data needed by the
// validation function.
//
// For a validator to be invoked, a validation function must be registered with
// the validator description in the language that the function is defined in.
type CaveatDescriptor struct {
	Id        uniqueid.Id // The identifier of the caveat validation function.
	ParamType *vdl.Type   // The type of the parameter expected by the validation function.
}

func (CaveatDescriptor) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.CaveatDescriptor"`
}) {
}

func (m *CaveatDescriptor) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Id == uniqueid.Id{})
	if var4 {
		if err := fieldsTarget1.ZeroField("Id"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Id")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Id.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.ParamType == nil || m.ParamType == vdl.AnyType)
	if var7 {
		if err := fieldsTarget1.ZeroField("ParamType"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("ParamType")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			typeObjectVal8 := m.ParamType
			if typeObjectVal8 == nil {
				typeObjectVal8 = vdl.AnyType
			}
			if err := fieldTarget6.FromTypeObject(typeObjectVal8); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *CaveatDescriptor) MakeVDLTarget() vdl.Target {
	return &CaveatDescriptorTarget{Value: m}
}

type CaveatDescriptorTarget struct {
	Value           *CaveatDescriptor
	idTarget        uniqueid.IdTarget
	paramTypeTarget vdl.TypeObjectTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*CaveatDescriptor)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *CaveatDescriptorTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Id":
		t.idTarget.Value = &t.Value.Id
		target, err := &t.idTarget, error(nil)
		return nil, target, err
	case "ParamType":
		t.paramTypeTarget.Value = &t.Value.ParamType
		target, err := &t.paramTypeTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *CaveatDescriptorTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *CaveatDescriptorTarget) ZeroField(name string) error {
	switch name {
	case "Id":
		t.Value.Id = uniqueid.Id{}
		return nil
	case "ParamType":
		t.Value.ParamType = vdl.AnyType
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *CaveatDescriptorTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x CaveatDescriptor) VDLIsZero() bool {
	if x.Id != (uniqueid.Id{}) {
		return false
	}
	if x.ParamType != nil && x.ParamType != vdl.AnyType {
		return false
	}
	return true
}

func (x CaveatDescriptor) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*CaveatDescriptor)(nil)).Elem()); err != nil {
		return err
	}
	if x.Id != (uniqueid.Id{}) {
		if err := enc.NextField("Id"); err != nil {
			return err
		}
		if err := x.Id.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.ParamType != nil && x.ParamType != vdl.AnyType {
		if err := enc.NextField("ParamType"); err != nil {
			return err
		}
		if err := x.ParamType.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CaveatDescriptor) VDLRead(dec vdl.Decoder) error {
	*x = CaveatDescriptor{
		ParamType: vdl.AnyType,
	}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Id":
			if err := x.Id.VDLRead(dec); err != nil {
				return err
			}
		case "ParamType":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.ParamType, err = dec.DecodeTypeObject(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// WireBlessings encapsulates wire format of a set of blessings and the
// corresponding cryptographic proof that binds them to a principal
// (identified by a public key).
//
// This structure is the "wire" format for sending and receiving blessings
// in RPCs or marshaling to persistent storage. Typically, languages will
// provide a factory function that converts this wire representation to
// a more usable object to inspect and manipulate these blessings.
type WireBlessings struct {
	// CertificateChains is an array of chains of certificates that bind
	// a blessing to the public key in the last certificate of the chain.
	CertificateChains [][]Certificate
}

func (WireBlessings) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.WireBlessings"`
}) {
}

func (m *WireBlessings) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.CertificateChains) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("CertificateChains"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("CertificateChains")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget5, err := fieldTarget3.StartList(tt.NonOptional().Field(0).Type, len(m.CertificateChains))
			if err != nil {
				return err
			}
			for i, elem7 := range m.CertificateChains {
				elemTarget6, err := listTarget5.StartElem(i)
				if err != nil {
					return err
				}

				listTarget8, err := elemTarget6.StartList(tt.NonOptional().Field(0).Type.Elem(), len(elem7))
				if err != nil {
					return err
				}
				for i, elem10 := range elem7 {
					elemTarget9, err := listTarget8.StartElem(i)
					if err != nil {
						return err
					}

					if err := elem10.FillVDLTarget(elemTarget9, tt.NonOptional().Field(0).Type.Elem().Elem()); err != nil {
						return err
					}
					if err := listTarget8.FinishElem(elemTarget9); err != nil {
						return err
					}
				}
				if err := elemTarget6.FinishList(listTarget8); err != nil {
					return err
				}
				if err := listTarget5.FinishElem(elemTarget6); err != nil {
					return err
				}
			}
			if err := fieldTarget3.FinishList(listTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *WireBlessings) MakeVDLTarget() vdl.Target {
	return nil
}

type WireBlessingsTarget struct {
	Value                   *Blessings
	wireValue               WireBlessings
	certificateChainsTarget __VDLTarget4_list
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *WireBlessingsTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
	t.wireValue = WireBlessings{}
	if ttWant := vdl.TypeOf((*WireBlessings)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *WireBlessingsTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "CertificateChains":
		t.certificateChainsTarget.Value = &t.wireValue.CertificateChains
		target, err := &t.certificateChainsTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *WireBlessingsTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *WireBlessingsTarget) ZeroField(name string) error {
	switch name {
	case "CertificateChains":
		t.wireValue.CertificateChains = [][]Certificate(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *WireBlessingsTarget) FinishFields(_ vdl.FieldsTarget) error {

	if err := WireBlessingsToNative(t.wireValue, t.Value); err != nil {
		return err
	}
	return nil
}

// [][]Certificate
type __VDLTarget4_list struct {
	Value      *[][]Certificate
	elemTarget __VDLTarget5_list
	vdl.TargetBase
	vdl.ListTargetBase
}

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

	if ttWant := vdl.TypeOf((*[][]Certificate)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([][]Certificate, len)
	} else {
		*t.Value = (*t.Value)[:len]
	}
	return t, nil
}
func (t *__VDLTarget4_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 *__VDLTarget4_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget4_list) FinishList(elem vdl.ListTarget) error {

	return nil
}

// []Certificate
type __VDLTarget5_list struct {
	Value      *[]Certificate
	elemTarget CertificateTarget
	vdl.TargetBase
	vdl.ListTargetBase
}

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

	if ttWant := vdl.TypeOf((*[]Certificate)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	if cap(*t.Value) < len {
		*t.Value = make([]Certificate, len)
	} else {
		*t.Value = (*t.Value)[:len]
	}
	return t, nil
}
func (t *__VDLTarget5_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 *__VDLTarget5_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget5_list) FinishList(elem vdl.ListTarget) error {

	return nil
}

func (x WireBlessings) VDLIsZero() bool {
	if len(x.CertificateChains) != 0 {
		return false
	}
	return true
}

func (x WireBlessings) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*WireBlessings)(nil)).Elem()); err != nil {
		return err
	}
	if len(x.CertificateChains) != 0 {
		if err := enc.NextField("CertificateChains"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_4(enc, x.CertificateChains); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_4(enc vdl.Encoder, x [][]Certificate) error {
	if err := enc.StartValue(vdl.TypeOf((*[][]Certificate)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_5(enc, x[i]); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_5(enc vdl.Encoder, x []Certificate) error {
	if err := enc.StartValue(vdl.TypeOf((*[]Certificate)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := x[i].VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *WireBlessings) VDLRead(dec vdl.Decoder) error {
	*x = WireBlessings{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "CertificateChains":
			if err := __VDLReadAnon_list_4(dec, &x.CertificateChains); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_4(dec vdl.Decoder, x *[][]Certificate) 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 = make([][]Certificate, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem []Certificate
		if err := __VDLReadAnon_list_5(dec, &elem); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

func __VDLReadAnon_list_5(dec vdl.Decoder, x *[]Certificate) 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 = make([]Certificate, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem Certificate
		if err := elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

type (
	// WireDischarge represents any single field of the WireDischarge union type.
	//
	// WireDischarge encapsulates the wire format of a third-party caveat
	// Discharge.
	WireDischarge interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the WireDischarge union type.
		__VDLReflect(__WireDischargeReflect)
		FillVDLTarget(vdl.Target, *vdl.Type) error
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// WireDischargePublicKey represents field PublicKey of the WireDischarge union type.
	WireDischargePublicKey struct{ Value PublicKeyDischarge } // Discharge for PublicKeyThirdPartyCaveat
	// __WireDischargeReflect describes the WireDischarge union type.
	__WireDischargeReflect struct {
		Name               string `vdl:"v.io/v23/security.WireDischarge"`
		Type               WireDischarge
		UnionTargetFactory wireDischargeTargetFactory
		Union              struct {
			PublicKey WireDischargePublicKey
		}
	}
)

func (x WireDischargePublicKey) Index() int                          { return 0 }
func (x WireDischargePublicKey) Interface() interface{}              { return x.Value }
func (x WireDischargePublicKey) Name() string                        { return "PublicKey" }
func (x WireDischargePublicKey) __VDLReflect(__WireDischargeReflect) {}

func (m WireDischargePublicKey) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("PublicKey")
	if err != nil {
		return err
	}

	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m WireDischargePublicKey) MakeVDLTarget() vdl.Target {
	return nil
}

type WireDischargeTarget struct {
	Value     *Discharge
	wireValue WireDischarge
	fieldName string

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *WireDischargeTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
	if ttWant := vdl.TypeOf((*WireDischarge)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	t.wireValue = WireDischarge(WireDischargePublicKey{})
	return t, nil
}
func (t *WireDischargeTarget) StartField(name string) (key, field vdl.Target, _ error) {
	t.fieldName = name
	switch name {
	case "PublicKey":
		val := PublicKeyDischarge{}
		return nil, &PublicKeyDischargeTarget{Value: &val}, nil
	default:
		return nil, nil, fmt.Errorf("field %s not in union v.io/v23/security.WireDischarge", name)
	}
}
func (t *WireDischargeTarget) FinishField(_, fieldTarget vdl.Target) error {
	switch t.fieldName {
	case "PublicKey":
		t.wireValue = WireDischargePublicKey{*(fieldTarget.(*PublicKeyDischargeTarget)).Value}
	}
	return nil
}
func (t *WireDischargeTarget) FinishFields(_ vdl.FieldsTarget) error {

	if err := WireDischargeToNative(t.wireValue, t.Value); err != nil {
		return err
	}
	return nil
}

type wireDischargeTargetFactory struct{}

func (t wireDischargeTargetFactory) VDLMakeUnionTarget(union interface{}) (vdl.Target, error) {
	if typedUnion, ok := union.(*Discharge); ok {
		return &WireDischargeTarget{Value: typedUnion}, nil
	}
	return nil, fmt.Errorf("got %T, want *Discharge", union)
}

func (x WireDischargePublicKey) VDLIsZero() bool {
	return x.Value.VDLIsZero()
}

func (x WireDischargePublicKey) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*WireDischarge)(nil))); err != nil {
		return err
	}
	if err := enc.NextField("PublicKey"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadWireDischarge(dec vdl.Decoder, x *WireDischarge) 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 union %T, from %v", x, dec.Type())
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "PublicKey":
		var field WireDischargePublicKey
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "":
		return fmt.Errorf("missing field in union %T, from %v", x, dec.Type())
	default:
		return fmt.Errorf("field %q not in union %T, from %v", f, x, dec.Type())
	}
	switch f, err := dec.NextField(); {
	case err != nil:
		return err
	case f != "":
		return fmt.Errorf("extra field %q in union %T, from %v", f, x, dec.Type())
	}
	return dec.FinishValue()
}

// RejectedBlessing describes why a blessing failed validation.
type RejectedBlessing struct {
	Blessing string
	Err      error
}

func (RejectedBlessing) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/security.RejectedBlessing"`
}) {
}

func (m *RejectedBlessing) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Blessing == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Blessing"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Blessing")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Blessing), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Err == (error)(nil))
	if var7 {
		if err := fieldsTarget1.ZeroField("Err"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Err")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			var wireError8 vdl.WireError
			if err := verror.WireFromNative(&wireError8, m.Err); err != nil {
				return err
			}
			if err := wireError8.FillVDLTarget(fieldTarget6, vdl.ErrorType); err != nil {
				return err
			}

			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *RejectedBlessing) MakeVDLTarget() vdl.Target {
	return &RejectedBlessingTarget{Value: m}
}

type RejectedBlessingTarget struct {
	Value          *RejectedBlessing
	blessingTarget vdl.StringTarget
	errTarget      verror.ErrorTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*RejectedBlessing)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *RejectedBlessingTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Blessing":
		t.blessingTarget.Value = &t.Value.Blessing
		target, err := &t.blessingTarget, error(nil)
		return nil, target, err
	case "Err":
		t.errTarget.Value = &t.Value.Err
		target, err := &t.errTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *RejectedBlessingTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *RejectedBlessingTarget) ZeroField(name string) error {
	switch name {
	case "Blessing":
		t.Value.Blessing = ""
		return nil
	case "Err":
		t.Value.Err = (error)(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *RejectedBlessingTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x RejectedBlessing) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*RejectedBlessing)(nil)).Elem()); err != nil {
		return err
	}
	if x.Blessing != "" {
		if err := enc.NextField("Blessing"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Blessing); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Err != nil {
		if err := enc.NextField("Err"); err != nil {
			return err
		}
		if err := verror.VDLWrite(enc, x.Err); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *RejectedBlessing) VDLRead(dec vdl.Decoder) error {
	*x = RejectedBlessing{}
	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())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Blessing":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Blessing, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Err":
			if err := verror.VDLRead(dec, &x.Err); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// Type-check native conversion functions.
var (
	_ func(WireBlessings, *Blessings) error = WireBlessingsToNative
	_ func(*WireBlessings, Blessings) error = WireBlessingsFromNative
	_ func(WireDischarge, *Discharge) error = WireDischargeToNative
	_ func(*WireDischarge, Discharge) error = WireDischargeFromNative
)

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

// ConstCaveat represents a caveat that either always validates or never validates.
var ConstCaveat = CaveatDescriptor{
	ParamType: vdl.BoolType,
}

// ExpiryCaveat represents a caveat that validates iff the current time is no later
// the specified time.Time.
var ExpiryCaveat = CaveatDescriptor{
	Id: uniqueid.Id{
		166,
		76,
		45,
		1,
		25,
		251,
		163,
		52,
		128,
		113,
		254,
		235,
		47,
		48,
		128,
		0,
	},
	ParamType: vdl.TypeOf((*vdltime.Time)(nil)).Elem(),
}

// MethodCaveat represents a caveat that validates iff the method being
// invoked is included in this list. An empty list implies that the caveat is invalid.
var MethodCaveat = CaveatDescriptor{
	Id: uniqueid.Id{
		84,
		166,
		118,
		57,
		129,
		55,
		24,
		126,
		205,
		178,
		109,
		45,
		105,
		186,
		0,
		3,
	},
	ParamType: vdl.TypeOf((*[]string)(nil)),
}
var PublicKeyThirdPartyCaveat = CaveatDescriptor{
	Id: uniqueid.Id{
		121,
		114,
		206,
		23,
		74,
		123,
		169,
		63,
		121,
		84,
		125,
		118,
		156,
		145,
		128,
		0,
	},
	ParamType: vdl.TypeOf((*publicKeyThirdPartyCaveatParam)(nil)).Elem(),
}

// PeerBlessingsCaveat represents a caveat that validates iff the peer being communicated
// with (local end of the call) has a blessing name matching at least one of the patterns
// in the list. An empty list implies that the caveat is invalid.
var PeerBlessingsCaveat = CaveatDescriptor{
	Id: uniqueid.Id{
		5,
		119,
		248,
		86,
		76,
		142,
		95,
		254,
		255,
		142,
		43,
		31,
		77,
		109,
		128,
		0,
	},
	ParamType: vdl.TypeOf((*[]BlessingPattern)(nil)),
}

// NoExtension is an optional terminator for a blessing pattern indicating that the pattern
// cannot match any extensions of the blessing from that point onwards.
const NoExtension = BlessingPattern("$")

// TODO(ataly, ashankar): The semantics of AllPrincipals breaks monotonicity in
// AccessLists with NotIn clauses. For instance, the AccessList "In: {AllPrincipals}, NotIn: {"foo"}
// matches the principal that presents no recognizable blessings ([]) however does not
// match the principal that presents "foo" as the only recognizable blessings (["foo"])
// We need to sort this out.
const AllPrincipals = BlessingPattern("...")  // Glob pattern that matches all blessings.
const ChainSeparator = ":"                    // ChainSeparator joins blessing names to form a blessing chain name.
const SHA1Hash = Hash("SHA1")                 // SHA1 cryptographic hash function defined in RFC3174.
const SHA256Hash = Hash("SHA256")             // SHA256 cryptographic hash function defined  in FIPS 180-4.
const SHA384Hash = Hash("SHA384")             // SHA384 cryptographic hash function defined in FIPS 180-2.
const SHA512Hash = Hash("SHA512")             // SHA512 cryptographic hash function defined in FIPS 180-2.
const SignatureForMessageSigning = "S1"       // Signature.Purpose used by a Principal to sign arbitrary messages.
const SignatureForBlessingCertificates = "B1" // Signature.Purpose used by a Principal when signing Certificates for creating blessings.
const SignatureForDischarge = "D1"            // Signature.Purpose used by a Principal when signing discharges for public-key based third-party caveats.

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

var (
	ErrCaveatNotRegistered           = verror.Register("v.io/v23/security.CaveatNotRegistered", verror.NoRetry, "{1:}{2:} no validation function registered for caveat id {3}")
	ErrCaveatParamAny                = verror.Register("v.io/v23/security.CaveatParamAny", verror.NoRetry, "{1:}{2:} caveat {3} uses illegal param type any")
	ErrCaveatParamTypeMismatch       = verror.Register("v.io/v23/security.CaveatParamTypeMismatch", verror.NoRetry, "{1:}{2:} bad param type: caveat {3} got {4}, want {5}")
	ErrCaveatParamCoding             = verror.Register("v.io/v23/security.CaveatParamCoding", verror.NoRetry, "{1:}{2:} unable to encode/decode caveat param(type={4}) for caveat {3}: {5}")
	ErrCaveatValidation              = verror.Register("v.io/v23/security.CaveatValidation", verror.NoRetry, "{1:}{2:} caveat validation failed: {3}")
	ErrConstCaveatValidation         = verror.Register("v.io/v23/security.ConstCaveatValidation", verror.NoRetry, "{1:}{2:} false const caveat always fails validation")
	ErrExpiryCaveatValidation        = verror.Register("v.io/v23/security.ExpiryCaveatValidation", verror.NoRetry, "{1:}{2:} now({3}) is after expiry({4})")
	ErrMethodCaveatValidation        = verror.Register("v.io/v23/security.MethodCaveatValidation", verror.NoRetry, "{1:}{2:} method {3} not in list {4}")
	ErrPeerBlessingsCaveatValidation = verror.Register("v.io/v23/security.PeerBlessingsCaveatValidation", verror.NoRetry, "{1:}{2:} patterns in peer blessings caveat {4} not matched by the peer {3}")
	ErrUnrecognizedRoot              = verror.Register("v.io/v23/security.UnrecognizedRoot", verror.NoRetry, "{1:}{2:} unrecognized public key {3} in root certificate{:4}")
	ErrAuthorizationFailed           = verror.Register("v.io/v23/security.AuthorizationFailed", verror.NoRetry, "{1:}{2:} principal with blessings {3} (rejected {4}) is not authorized by principal with blessings {5}")
	ErrInvalidSigningBlessingCaveat  = verror.Register("v.io/v23/security.InvalidSigningBlessingCaveat", verror.NoRetry, "{1:}{2:} blessing has caveat with UUID {3} which makes it unsuitable for signing -- please use blessings with just Expiry caveats")
	ErrPublicKeyNotAllowed           = verror.Register("v.io/v23/security.PublicKeyNotAllowed", verror.NoRetry, "{1:}{2:} peer has public key {3}, not the authorized public key {4}")
	ErrEndpointAuthorizationFailed   = verror.Register("v.io/v23/security.EndpointAuthorizationFailed", verror.NoRetry, "{1:}{2:} blessings in endpoint {3} not matched by blessings presented: {4} (rejected {5})")
)

// NewErrCaveatNotRegistered returns an error with the ErrCaveatNotRegistered ID.
func NewErrCaveatNotRegistered(ctx *context.T, id uniqueid.Id) error {
	return verror.New(ErrCaveatNotRegistered, ctx, id)
}

// NewErrCaveatParamAny returns an error with the ErrCaveatParamAny ID.
func NewErrCaveatParamAny(ctx *context.T, id uniqueid.Id) error {
	return verror.New(ErrCaveatParamAny, ctx, id)
}

// NewErrCaveatParamTypeMismatch returns an error with the ErrCaveatParamTypeMismatch ID.
func NewErrCaveatParamTypeMismatch(ctx *context.T, id uniqueid.Id, got *vdl.Type, want *vdl.Type) error {
	return verror.New(ErrCaveatParamTypeMismatch, ctx, id, got, want)
}

// NewErrCaveatParamCoding returns an error with the ErrCaveatParamCoding ID.
func NewErrCaveatParamCoding(ctx *context.T, id uniqueid.Id, typ *vdl.Type, err error) error {
	return verror.New(ErrCaveatParamCoding, ctx, id, typ, err)
}

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

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

// NewErrExpiryCaveatValidation returns an error with the ErrExpiryCaveatValidation ID.
func NewErrExpiryCaveatValidation(ctx *context.T, currentTime time.Time, expiryTime time.Time) error {
	return verror.New(ErrExpiryCaveatValidation, ctx, currentTime, expiryTime)
}

// NewErrMethodCaveatValidation returns an error with the ErrMethodCaveatValidation ID.
func NewErrMethodCaveatValidation(ctx *context.T, invokedMethod string, permittedMethods []string) error {
	return verror.New(ErrMethodCaveatValidation, ctx, invokedMethod, permittedMethods)
}

// NewErrPeerBlessingsCaveatValidation returns an error with the ErrPeerBlessingsCaveatValidation ID.
func NewErrPeerBlessingsCaveatValidation(ctx *context.T, peerBlessings []string, permittedPatterns []BlessingPattern) error {
	return verror.New(ErrPeerBlessingsCaveatValidation, ctx, peerBlessings, permittedPatterns)
}

// NewErrUnrecognizedRoot returns an error with the ErrUnrecognizedRoot ID.
func NewErrUnrecognizedRoot(ctx *context.T, rootKey string, details error) error {
	return verror.New(ErrUnrecognizedRoot, ctx, rootKey, details)
}

// NewErrAuthorizationFailed returns an error with the ErrAuthorizationFailed ID.
func NewErrAuthorizationFailed(ctx *context.T, remote []string, remoteErr []RejectedBlessing, local []string) error {
	return verror.New(ErrAuthorizationFailed, ctx, remote, remoteErr, local)
}

// NewErrInvalidSigningBlessingCaveat returns an error with the ErrInvalidSigningBlessingCaveat ID.
func NewErrInvalidSigningBlessingCaveat(ctx *context.T, id uniqueid.Id) error {
	return verror.New(ErrInvalidSigningBlessingCaveat, ctx, id)
}

// NewErrPublicKeyNotAllowed returns an error with the ErrPublicKeyNotAllowed ID.
func NewErrPublicKeyNotAllowed(ctx *context.T, got string, want string) error {
	return verror.New(ErrPublicKeyNotAllowed, ctx, got, want)
}

// NewErrEndpointAuthorizationFailed returns an error with the ErrEndpointAuthorizationFailed ID.
func NewErrEndpointAuthorizationFailed(ctx *context.T, endpoint string, remote []string, rejected []RejectedBlessing) error {
	return verror.New(ErrEndpointAuthorizationFailed, ctx, endpoint, remote, rejected)
}

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 native type conversions first, so that vdl.TypeOf works.
	vdl.RegisterNative(WireBlessingsToNative, WireBlessingsFromNative)
	vdl.RegisterNative(WireDischargeToNative, WireDischargeFromNative)

	// Register types.
	vdl.Register((*nonce)(nil))
	vdl.Register((*Caveat)(nil))
	vdl.Register((*ThirdPartyRequirements)(nil))
	vdl.Register((*publicKeyThirdPartyCaveatParam)(nil))
	vdl.Register((*Hash)(nil))
	vdl.Register((*Signature)(nil))
	vdl.Register((*PublicKeyDischarge)(nil))
	vdl.Register((*BlessingPattern)(nil))
	vdl.Register((*DischargeImpetus)(nil))
	vdl.Register((*Certificate)(nil))
	vdl.Register((*CaveatDescriptor)(nil))
	vdl.Register((*WireBlessings)(nil))
	vdl.Register((*WireDischarge)(nil))
	vdl.Register((*RejectedBlessing)(nil))

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCaveatNotRegistered.ID), "{1:}{2:} no validation function registered for caveat id {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCaveatParamAny.ID), "{1:}{2:} caveat {3} uses illegal param type any")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCaveatParamTypeMismatch.ID), "{1:}{2:} bad param type: caveat {3} got {4}, want {5}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCaveatParamCoding.ID), "{1:}{2:} unable to encode/decode caveat param(type={4}) for caveat {3}: {5}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCaveatValidation.ID), "{1:}{2:} caveat validation failed: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrConstCaveatValidation.ID), "{1:}{2:} false const caveat always fails validation")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrExpiryCaveatValidation.ID), "{1:}{2:} now({3}) is after expiry({4})")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrMethodCaveatValidation.ID), "{1:}{2:} method {3} not in list {4}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrPeerBlessingsCaveatValidation.ID), "{1:}{2:} patterns in peer blessings caveat {4} not matched by the peer {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrUnrecognizedRoot.ID), "{1:}{2:} unrecognized public key {3} in root certificate{:4}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrAuthorizationFailed.ID), "{1:}{2:} principal with blessings {3} (rejected {4}) is not authorized by principal with blessings {5}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidSigningBlessingCaveat.ID), "{1:}{2:} blessing has caveat with UUID {3} which makes it unsuitable for signing -- please use blessings with just Expiry caveats")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrPublicKeyNotAllowed.ID), "{1:}{2:} peer has public key {3}, not the authorized public key {4}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrEndpointAuthorizationFailed.ID), "{1:}{2:} blessings in endpoint {3} not matched by blessings presented: {4} (rejected {5})")

	return struct{}{}
}
