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

package conn

import (
	"fmt"
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/security"
	"v.io/v23/vdl"
	"v.io/v23/verror"
	"v.io/x/ref/lib/security/bcrypter"
)

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

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

// Blessings is used to transport blessings between the two ends of a Conn.
// Since blessings can be large, we try not to send them more than once by
// associating them with an integer key (BKey). Thereafter we refer to them
// by their key.
type Blessings struct {
	Blessings security.Blessings
	BKey      uint64
}

func (Blessings) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/runtime/internal/flow/conn.Blessings"`
}) {
}

func (x Blessings) VDLIsZero() bool {
	if !x.Blessings.IsZero() {
		return false
	}
	if x.BKey != 0 {
		return false
	}
	return true
}

func (x Blessings) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	if !x.Blessings.IsZero() {
		if err := enc.NextField("Blessings"); err != nil {
			return err
		}
		var wire security.WireBlessings
		if err := security.WireBlessingsFromNative(&wire, x.Blessings); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.BKey != 0 {
		if err := enc.NextFieldValueUint("BKey", vdl.Uint64Type, x.BKey); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Blessings) VDLRead(dec vdl.Decoder) error {
	*x = Blessings{}
	if err := dec.StartValue(__VDLType_struct_1); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Blessings":
			var wire security.WireBlessings
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := security.WireBlessingsToNative(wire, &x.Blessings); err != nil {
				return err
			}
		case "BKey":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.BKey = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// EncryptedBlessings is used to transport encrypted blessings between the
// two ends of a Conn. The encryption is with respect to a set of blessing
// patterns that define the set of peers that are allowed to see the blessings.
// Since encrypted blessings can be large, we try not to send them more than
// once by associating them with an integer key (BKey). Thereafter we refer to
// them by their key.
type EncryptedBlessings struct {
	Ciphertexts []bcrypter.WireCiphertext
	BKey        uint64
}

func (EncryptedBlessings) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/runtime/internal/flow/conn.EncryptedBlessings"`
}) {
}

func (x EncryptedBlessings) VDLIsZero() bool {
	if len(x.Ciphertexts) != 0 {
		return false
	}
	if x.BKey != 0 {
		return false
	}
	return true
}

func (x EncryptedBlessings) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	if len(x.Ciphertexts) != 0 {
		if err := enc.NextField("Ciphertexts"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Ciphertexts); err != nil {
			return err
		}
	}
	if x.BKey != 0 {
		if err := enc.NextFieldValueUint("BKey", vdl.Uint64Type, x.BKey); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []bcrypter.WireCiphertext) error {
	if err := enc.StartValue(__VDLType_list_4); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *EncryptedBlessings) VDLRead(dec vdl.Decoder) error {
	*x = EncryptedBlessings{}
	if err := dec.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Ciphertexts":
			if err := __VDLReadAnon_list_1(dec, &x.Ciphertexts); err != nil {
				return err
			}
		case "BKey":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.BKey = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]bcrypter.WireCiphertext) error {
	if err := dec.StartValue(__VDLType_list_4); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]bcrypter.WireCiphertext, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem bcrypter.WireCiphertext
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
			*x = append(*x, elem)
		}
	}
}

// Discharges is used to transport discharges between the two ends of a Conn.
// Since discharges can be large, we try not to send them more than once by
// associating them with an integer key (DKey). Thereafter we refer to them
// by their key.
// Discharges also contains the BKey of the blessings with which the discharges
// are associated with.
type Discharges struct {
	Discharges []security.Discharge
	DKey       uint64
	BKey       uint64
}

func (Discharges) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/runtime/internal/flow/conn.Discharges"`
}) {
}

func (x Discharges) VDLIsZero() bool {
	if len(x.Discharges) != 0 {
		return false
	}
	if x.DKey != 0 {
		return false
	}
	if x.BKey != 0 {
		return false
	}
	return true
}

func (x Discharges) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	if len(x.Discharges) != 0 {
		if err := enc.NextField("Discharges"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.Discharges); err != nil {
			return err
		}
	}
	if x.DKey != 0 {
		if err := enc.NextFieldValueUint("DKey", vdl.Uint64Type, x.DKey); err != nil {
			return err
		}
	}
	if x.BKey != 0 {
		if err := enc.NextFieldValueUint("BKey", vdl.Uint64Type, x.BKey); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_2(enc vdl.Encoder, x []security.Discharge) error {
	if err := enc.StartValue(__VDLType_list_7); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		var wire security.WireDischarge
		if err := security.WireDischargeFromNative(&wire, elem); err != nil {
			return err
		}
		switch {
		case wire == nil:
			// Write the zero value of the union type.
			if err := vdl.ZeroValue(__VDLType_union_8).VDLWrite(enc); err != nil {
				return err
			}
		default:
			if err := wire.VDLWrite(enc); err != nil {
				return err
			}
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Discharges) VDLRead(dec vdl.Decoder) error {
	*x = Discharges{}
	if err := dec.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Discharges":
			if err := __VDLReadAnon_list_2(dec, &x.Discharges); err != nil {
				return err
			}
		case "DKey":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.DKey = value
			}
		case "BKey":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.BKey = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_2(dec vdl.Decoder, x *[]security.Discharge) error {
	if err := dec.StartValue(__VDLType_list_7); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]security.Discharge, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem security.Discharge
			var wire security.WireDischarge
			if err := security.VDLReadWireDischarge(dec, &wire); err != nil {
				return err
			}
			if err := security.WireDischargeToNative(wire, &elem); err != nil {
				return err
			}
			*x = append(*x, elem)
		}
	}
}

// EncryptedDischarges is used to transport encrypted discharges between the
// two ends of a Conn. The encryption is with respect to a set of blessing
// patterns that define the set of peers that are allowed to see the discharges.
// Since discharges can be large, we try not to send them more than once by
// associating them with an integer key (DKey). Thereafter we refer to them
// by their key.
// EncryptedDischarges also contains the BKey of the blessings with which the
// plaintext discharges are associated with.
type EncryptedDischarges struct {
	Ciphertexts []bcrypter.WireCiphertext
	DKey        uint64
	BKey        uint64
}

func (EncryptedDischarges) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/runtime/internal/flow/conn.EncryptedDischarges"`
}) {
}

func (x EncryptedDischarges) VDLIsZero() bool {
	if len(x.Ciphertexts) != 0 {
		return false
	}
	if x.DKey != 0 {
		return false
	}
	if x.BKey != 0 {
		return false
	}
	return true
}

func (x EncryptedDischarges) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_9); err != nil {
		return err
	}
	if len(x.Ciphertexts) != 0 {
		if err := enc.NextField("Ciphertexts"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Ciphertexts); err != nil {
			return err
		}
	}
	if x.DKey != 0 {
		if err := enc.NextFieldValueUint("DKey", vdl.Uint64Type, x.DKey); err != nil {
			return err
		}
	}
	if x.BKey != 0 {
		if err := enc.NextFieldValueUint("BKey", vdl.Uint64Type, x.BKey); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *EncryptedDischarges) VDLRead(dec vdl.Decoder) error {
	*x = EncryptedDischarges{}
	if err := dec.StartValue(__VDLType_struct_9); err != nil {
		return err
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Ciphertexts":
			if err := __VDLReadAnon_list_1(dec, &x.Ciphertexts); err != nil {
				return err
			}
		case "DKey":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.DKey = value
			}
		case "BKey":
			switch value, err := dec.ReadValueUint(64); {
			case err != nil:
				return err
			default:
				x.BKey = value
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type (
	// BlessingsFlowMessage represents any single field of the BlessingsFlowMessage union type.
	//
	// BlessingsFlowMessage is used to send either a Blessings, Discharges, EncryptedBlessings
	// or EncryptedDischarges object over the wire.
	BlessingsFlowMessage 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 BlessingsFlowMessage union type.
		__VDLReflect(__BlessingsFlowMessageReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// BlessingsFlowMessageBlessings represents field Blessings of the BlessingsFlowMessage union type.
	BlessingsFlowMessageBlessings struct{ Value Blessings }
	// BlessingsFlowMessageDischarges represents field Discharges of the BlessingsFlowMessage union type.
	BlessingsFlowMessageDischarges struct{ Value Discharges }
	// BlessingsFlowMessageEncryptedBlessings represents field EncryptedBlessings of the BlessingsFlowMessage union type.
	BlessingsFlowMessageEncryptedBlessings struct{ Value EncryptedBlessings }
	// BlessingsFlowMessageEncryptedDischarges represents field EncryptedDischarges of the BlessingsFlowMessage union type.
	BlessingsFlowMessageEncryptedDischarges struct{ Value EncryptedDischarges }
	// __BlessingsFlowMessageReflect describes the BlessingsFlowMessage union type.
	__BlessingsFlowMessageReflect struct {
		Name  string `vdl:"v.io/x/ref/runtime/internal/flow/conn.BlessingsFlowMessage"`
		Type  BlessingsFlowMessage
		Union struct {
			Blessings           BlessingsFlowMessageBlessings
			Discharges          BlessingsFlowMessageDischarges
			EncryptedBlessings  BlessingsFlowMessageEncryptedBlessings
			EncryptedDischarges BlessingsFlowMessageEncryptedDischarges
		}
	}
)

func (x BlessingsFlowMessageBlessings) Index() int                                 { return 0 }
func (x BlessingsFlowMessageBlessings) Interface() interface{}                     { return x.Value }
func (x BlessingsFlowMessageBlessings) Name() string                               { return "Blessings" }
func (x BlessingsFlowMessageBlessings) __VDLReflect(__BlessingsFlowMessageReflect) {}

func (x BlessingsFlowMessageDischarges) Index() int                                 { return 1 }
func (x BlessingsFlowMessageDischarges) Interface() interface{}                     { return x.Value }
func (x BlessingsFlowMessageDischarges) Name() string                               { return "Discharges" }
func (x BlessingsFlowMessageDischarges) __VDLReflect(__BlessingsFlowMessageReflect) {}

func (x BlessingsFlowMessageEncryptedBlessings) Index() int                                 { return 2 }
func (x BlessingsFlowMessageEncryptedBlessings) Interface() interface{}                     { return x.Value }
func (x BlessingsFlowMessageEncryptedBlessings) Name() string                               { return "EncryptedBlessings" }
func (x BlessingsFlowMessageEncryptedBlessings) __VDLReflect(__BlessingsFlowMessageReflect) {}

func (x BlessingsFlowMessageEncryptedDischarges) Index() int                                 { return 3 }
func (x BlessingsFlowMessageEncryptedDischarges) Interface() interface{}                     { return x.Value }
func (x BlessingsFlowMessageEncryptedDischarges) Name() string                               { return "EncryptedDischarges" }
func (x BlessingsFlowMessageEncryptedDischarges) __VDLReflect(__BlessingsFlowMessageReflect) {}

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

func (x BlessingsFlowMessageDischarges) VDLIsZero() bool {
	return false
}

func (x BlessingsFlowMessageEncryptedBlessings) VDLIsZero() bool {
	return false
}

func (x BlessingsFlowMessageEncryptedDischarges) VDLIsZero() bool {
	return false
}

func (x BlessingsFlowMessageBlessings) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_10); err != nil {
		return err
	}
	if err := enc.NextField("Blessings"); 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 (x BlessingsFlowMessageDischarges) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_10); err != nil {
		return err
	}
	if err := enc.NextField("Discharges"); 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 (x BlessingsFlowMessageEncryptedBlessings) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_10); err != nil {
		return err
	}
	if err := enc.NextField("EncryptedBlessings"); 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 (x BlessingsFlowMessageEncryptedDischarges) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_10); err != nil {
		return err
	}
	if err := enc.NextField("EncryptedDischarges"); 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 VDLReadBlessingsFlowMessage(dec vdl.Decoder, x *BlessingsFlowMessage) error {
	if err := dec.StartValue(__VDLType_union_10); err != nil {
		return err
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "Blessings":
		var field BlessingsFlowMessageBlessings
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "Discharges":
		var field BlessingsFlowMessageDischarges
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "EncryptedBlessings":
		var field BlessingsFlowMessageEncryptedBlessings
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "EncryptedDischarges":
		var field BlessingsFlowMessageEncryptedDischarges
		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()
}

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

var (
	ErrMissingSetupOption       = verror.Register("v.io/x/ref/runtime/internal/flow/conn.MissingSetupOption", verror.NoRetry, "{1:}{2:} missing required setup option{:3}.")
	ErrUnexpectedMsg            = verror.Register("v.io/x/ref/runtime/internal/flow/conn.UnexpectedMsg", verror.NoRetry, "{1:}{2:} unexpected message type{:3}.")
	ErrConnectionClosed         = verror.Register("v.io/x/ref/runtime/internal/flow/conn.ConnectionClosed", verror.NoRetry, "{1:}{2:} connection closed.")
	ErrRemoteError              = verror.Register("v.io/x/ref/runtime/internal/flow/conn.RemoteError", verror.NoRetry, "{1:}{2:} remote end received err{:3}.")
	ErrSend                     = verror.Register("v.io/x/ref/runtime/internal/flow/conn.Send", verror.NoRetry, "{1:}{2:} failure sending {3} message to {4}{:5}.")
	ErrRecv                     = verror.Register("v.io/x/ref/runtime/internal/flow/conn.Recv", verror.NoRetry, "{1:}{2:} error reading from {3}{:4}")
	ErrCounterOverflow          = verror.Register("v.io/x/ref/runtime/internal/flow/conn.CounterOverflow", verror.NoRetry, "{1:}{2:} A remote process has sent more data than allowed.")
	ErrBlessingsFlowClosed      = verror.Register("v.io/x/ref/runtime/internal/flow/conn.BlessingsFlowClosed", verror.NoRetry, "{1:}{2:} The blessings flow was closed with error{:3}.")
	ErrInvalidChannelBinding    = verror.Register("v.io/x/ref/runtime/internal/flow/conn.InvalidChannelBinding", verror.NoRetry, "{1:}{2:} The channel binding was invalid.")
	ErrNoPublicKey              = verror.Register("v.io/x/ref/runtime/internal/flow/conn.NoPublicKey", verror.NoRetry, "{1:}{2:} No public key was received by the remote end.")
	ErrDialingNonServer         = verror.Register("v.io/x/ref/runtime/internal/flow/conn.DialingNonServer", verror.NoRetry, "{1:}{2:} You are attempting to dial on a connection with no remote server: {:3}.")
	ErrAcceptorBlessingsMissing = verror.Register("v.io/x/ref/runtime/internal/flow/conn.AcceptorBlessingsMissing", verror.NoRetry, "{1:}{2:} The acceptor did not send blessings.")
	ErrDialerBlessingsMissing   = verror.Register("v.io/x/ref/runtime/internal/flow/conn.DialerBlessingsMissing", verror.NoRetry, "{1:}{2:} The dialer did not send blessings.")
	ErrBlessingsNotBound        = verror.Register("v.io/x/ref/runtime/internal/flow/conn.BlessingsNotBound", verror.NoRetry, "{1:}{2:} blessings not bound to connection remote public key")
	ErrInvalidPeerFlow          = verror.Register("v.io/x/ref/runtime/internal/flow/conn.InvalidPeerFlow", verror.NoRetry, "{1:}{2:} peer has chosen flow id from local domain.")
	ErrChannelTimeout           = verror.Register("v.io/x/ref/runtime/internal/flow/conn.ChannelTimeout", verror.NoRetry, "{1:}{2:} the channel has become unresponsive.")
	ErrCannotDecryptBlessings   = verror.Register("v.io/x/ref/runtime/internal/flow/conn.CannotDecryptBlessings", verror.NoRetry, "{1:}{2:} cannot decrypt the encrypted blessings sent by peer{:3}")
	ErrCannotDecryptDischarges  = verror.Register("v.io/x/ref/runtime/internal/flow/conn.CannotDecryptDischarges", verror.NoRetry, "{1:}{2:} cannot decrypt the encrypted discharges sent by peer{:3}")
	ErrCannotEncryptBlessings   = verror.Register("v.io/x/ref/runtime/internal/flow/conn.CannotEncryptBlessings", verror.NoRetry, "{1:}{2:} cannot encyrpt blessings for peer {3}{:4}")
	ErrCannotEncryptDischarges  = verror.Register("v.io/x/ref/runtime/internal/flow/conn.CannotEncryptDischarges", verror.NoRetry, "{1:}{2:} cannot encrypt discharges for peers {3}{:4}")
	ErrNoCrypter                = verror.Register("v.io/x/ref/runtime/internal/flow/conn.NoCrypter", verror.NoRetry, "{1:}{2:} no blessings-based crypter available")
	ErrNoPrivateKey             = verror.Register("v.io/x/ref/runtime/internal/flow/conn.NoPrivateKey", verror.NoRetry, "{1:}{2:} no blessings private key available for decryption")
	ErrIdleConnKilled           = verror.Register("v.io/x/ref/runtime/internal/flow/conn.IdleConnKilled", verror.NoRetry, "{1:}{2:} Connection killed because idle expiry was reached.")
)

// NewErrMissingSetupOption returns an error with the ErrMissingSetupOption ID.
func NewErrMissingSetupOption(ctx *context.T, option string) error {
	return verror.New(ErrMissingSetupOption, ctx, option)
}

// NewErrUnexpectedMsg returns an error with the ErrUnexpectedMsg ID.
func NewErrUnexpectedMsg(ctx *context.T, typ string) error {
	return verror.New(ErrUnexpectedMsg, ctx, typ)
}

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

// NewErrRemoteError returns an error with the ErrRemoteError ID.
func NewErrRemoteError(ctx *context.T, msg string) error {
	return verror.New(ErrRemoteError, ctx, msg)
}

// NewErrSend returns an error with the ErrSend ID.
func NewErrSend(ctx *context.T, typ string, dest string, err error) error {
	return verror.New(ErrSend, ctx, typ, dest, err)
}

// NewErrRecv returns an error with the ErrRecv ID.
func NewErrRecv(ctx *context.T, src string, err error) error {
	return verror.New(ErrRecv, ctx, src, err)
}

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

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

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

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

// NewErrDialingNonServer returns an error with the ErrDialingNonServer ID.
func NewErrDialingNonServer(ctx *context.T, ep string) error {
	return verror.New(ErrDialingNonServer, ctx, ep)
}

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

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

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

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

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

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

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

// NewErrCannotEncryptBlessings returns an error with the ErrCannotEncryptBlessings ID.
func NewErrCannotEncryptBlessings(ctx *context.T, peers []security.BlessingPattern, err error) error {
	return verror.New(ErrCannotEncryptBlessings, ctx, peers, err)
}

// NewErrCannotEncryptDischarges returns an error with the ErrCannotEncryptDischarges ID.
func NewErrCannotEncryptDischarges(ctx *context.T, peers []security.BlessingPattern, err error) error {
	return verror.New(ErrCannotEncryptDischarges, ctx, peers, err)
}

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

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

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

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_struct_1 *vdl.Type
	__VDLType_struct_2 *vdl.Type
	__VDLType_struct_3 *vdl.Type
	__VDLType_list_4   *vdl.Type
	__VDLType_struct_5 *vdl.Type
	__VDLType_struct_6 *vdl.Type
	__VDLType_list_7   *vdl.Type
	__VDLType_union_8  *vdl.Type
	__VDLType_struct_9 *vdl.Type
	__VDLType_union_10 *vdl.Type
)

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true

	// Register types.
	vdl.Register((*Blessings)(nil))
	vdl.Register((*EncryptedBlessings)(nil))
	vdl.Register((*Discharges)(nil))
	vdl.Register((*EncryptedDischarges)(nil))
	vdl.Register((*BlessingsFlowMessage)(nil))

	// Initialize type definitions.
	__VDLType_struct_1 = vdl.TypeOf((*Blessings)(nil)).Elem()
	__VDLType_struct_2 = vdl.TypeOf((*security.WireBlessings)(nil)).Elem()
	__VDLType_struct_3 = vdl.TypeOf((*EncryptedBlessings)(nil)).Elem()
	__VDLType_list_4 = vdl.TypeOf((*[]bcrypter.WireCiphertext)(nil))
	__VDLType_struct_5 = vdl.TypeOf((*bcrypter.WireCiphertext)(nil)).Elem()
	__VDLType_struct_6 = vdl.TypeOf((*Discharges)(nil)).Elem()
	__VDLType_list_7 = vdl.TypeOf((*[]security.Discharge)(nil))
	__VDLType_union_8 = vdl.TypeOf((*security.WireDischarge)(nil))
	__VDLType_struct_9 = vdl.TypeOf((*EncryptedDischarges)(nil)).Elem()
	__VDLType_union_10 = vdl.TypeOf((*BlessingsFlowMessage)(nil))

	// Set error format strings.
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrMissingSetupOption.ID), "{1:}{2:} missing required setup option{:3}.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrUnexpectedMsg.ID), "{1:}{2:} unexpected message type{:3}.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrConnectionClosed.ID), "{1:}{2:} connection closed.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrRemoteError.ID), "{1:}{2:} remote end received err{:3}.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrSend.ID), "{1:}{2:} failure sending {3} message to {4}{:5}.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrRecv.ID), "{1:}{2:} error reading from {3}{:4}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCounterOverflow.ID), "{1:}{2:} A remote process has sent more data than allowed.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBlessingsFlowClosed.ID), "{1:}{2:} The blessings flow was closed with error{:3}.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidChannelBinding.ID), "{1:}{2:} The channel binding was invalid.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoPublicKey.ID), "{1:}{2:} No public key was received by the remote end.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrDialingNonServer.ID), "{1:}{2:} You are attempting to dial on a connection with no remote server: {:3}.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrAcceptorBlessingsMissing.ID), "{1:}{2:} The acceptor did not send blessings.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrDialerBlessingsMissing.ID), "{1:}{2:} The dialer did not send blessings.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrBlessingsNotBound.ID), "{1:}{2:} blessings not bound to connection remote public key")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrInvalidPeerFlow.ID), "{1:}{2:} peer has chosen flow id from local domain.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrChannelTimeout.ID), "{1:}{2:} the channel has become unresponsive.")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCannotDecryptBlessings.ID), "{1:}{2:} cannot decrypt the encrypted blessings sent by peer{:3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCannotDecryptDischarges.ID), "{1:}{2:} cannot decrypt the encrypted discharges sent by peer{:3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCannotEncryptBlessings.ID), "{1:}{2:} cannot encyrpt blessings for peer {3}{:4}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrCannotEncryptDischarges.ID), "{1:}{2:} cannot encrypt discharges for peers {3}{:4}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoCrypter.ID), "{1:}{2:} no blessings-based crypter available")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrNoPrivateKey.ID), "{1:}{2:} no blessings private key available for decryption")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(ErrIdleConnKilled.ID), "{1:}{2:} Connection killed because idle expiry was reached.")

	return struct{}{}
}
