// 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.

// Package verror implements an error reporting mechanism that works across
// programming environments, and a set of common errors.
//
// Each error has an identifier string, which is used for equality checks.
// E.g. a Javascript client can check if a Go server returned a NoExist error by
// checking the string identifier.  Error identifier strings start with the VDL
// package path to ensure uniqueness, e.g. "v.io/v23/verror.NoExist".
//
// Each error contains an action, which is the suggested action for a typical
// client to perform upon receiving the error.  E.g. some action codes represent
// whether to retry the operation after receiving the error.
//
// Each error also contains a list of typed parameters, and an error message.
// The error message is created by looking up a format string keyed on the error
// identifier, and applying the parameters to the format string.  This enables
// error messages to be generated in different languages.
//
// Examples
//
// To define a new error identifier, for example "someNewError", client code is
// expected to declare a variable like this:
//      var someNewError = verror.Register("my/package/name.someNewError", NoRetry,
//                                         "{1} {2} English text for new error")
// Text for other languages can be added to the default i18n Catalogue.
//
// If the error should cause a client to retry, consider replacing "NoRetry" with
// one of the other Action codes below.
//
// Errors are given parameters when used.  Conventionally, the first parameter
// is the name of the component (typically server or binary name), and the
// second is the name of the operation (such as an RPC or subcommand) that
// encountered the error.  Other parameters typically identify the object(s) on
// which the error occurred.  This convention is normally applied by New(),
// which fetches the language, component name and operation name from the
// context.T:
//      err = verror.New(someNewError, ctx, "object_on_which_error_occurred")
//
// The ExplicitNew() call can be used to specify these things explicitly:
//      err = verror.ExplicitNew(someNewError, i18n.GetLangID(ctx),
//              "my_component", "op_name", "procedure_name", "object_name")
// If the language, component and/or operation name are unknown, use i18n.NoLangID
// or the empty string, respectively.
//
// Because of the convention for the first two parameters, messages in the
// catalogue typically look like this (at least for left-to-right languages):
//      {1} {2} The new error {_}
// The tokens {1}, {2}, etc.  refer to the first and second positional parameters
// respectively, while {_} is replaced by the positional parameters not
// explicitly referred to elsewhere in the message.  Thus, given the parameters
// above, this would lead to the output:
//      my_component op_name The new error object_name
//
// If a substring is of the form {:<number>}, {<number>:}, {:<number>:}, {:_},
// {_:}, or {:_:}, and the corresponding parameters are not the empty string,
// the parameter is preceded by ": " or followed by ":" or both,
// respectively.  For example, if the format:
//      {3:} foo {2} bar{:_} ({3})
// is used with the cat.Format example above, it yields:
//      3rd: foo 2nd bar: 1st 4th (3rd)
//
// The Convert() and ExplicitConvert() calls are like New() and ExplicitNew(),
// but convert existing errors (with their parameters, if applicable)
// to verror errors with given language, component name, and operation name,
// if non-empty values for these are provided.  They also add a PC to a
// list of PC values to assist developers hunting for the error.
//
// If the context.T specified with New() or Convert() is nil, a default
// context is used, set by SetDefaultContext().  This can be used in standalone
// programmes, or in anciliary threads not associated with an RPC.  The user
// might do the following to get the language from the environment, and the
// programme name from Args[0]:
//     ctx := runtime.NewContext()
//     ctx = i18n.WithLangID(ctx, i18n.LangIDFromEnv())
//     ctx = verror.WithComponentName(ctx, os.Args[0])
//     verror.SetDefaultContext(ctx)
// A standalone tool might set the operation name to be a subcommand name, if
// any.  If the default context has not been set, the error generated has no
// language, component and operation values; they will be filled in by the
// first Convert() call that does have these values.
package verror

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"sync"

	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/vdl"
	"v.io/v23/vtrace"
)

// ID is a unique identifier for errors.
type ID string

// An ActionCode represents the action expected to be performed by a typical client
// receiving an error that perhaps it does not understand.
type ActionCode uint32

// Codes for ActionCode.
const (
	// Retry actions are encoded in the bottom few bits.
	RetryActionMask ActionCode = 3

	NoRetry         ActionCode = 0 // Do not retry.
	RetryConnection ActionCode = 1 // Renew high-level connection/context.
	RetryRefetch    ActionCode = 2 // Refetch and retry (e.g., out of date HTTP ETag)
	RetryBackoff    ActionCode = 3 // Backoff and retry a finite number of times.
)

// RetryAction returns the part of the ActionCode that indicates retry behaviour.
func (ac ActionCode) RetryAction() ActionCode {
	return ac & RetryActionMask
}

// An IDAction combines a unique identifier ID for errors with an ActionCode.
// The ID allows stable error checking across different error messages and
// different address spaces.  By convention the format for the identifier is
// "PKGPATH.NAME" - e.g. ErrIDFoo defined in the "v23/verror" package has id
// "v23/verror.ErrIDFoo".  It is unwise ever to create two IDActions that
// associate different ActionCodes with the same ID.
type IDAction struct {
	ID     ID
	Action ActionCode
}

// Register returns a IDAction with the given ID and Action fields, and
// inserts a message into the default i18n Catalogue in US English.
// Other languages can be added by adding to the Catalogue.
func Register(id ID, action ActionCode, englishText string) IDAction {
	i18n.Cat().SetWithBase(defaultLangID(i18n.NoLangID), i18n.MsgID(id), englishText)
	return IDAction{id, action}
}

// E is the in-memory representation of a verror error.
//
// The wire representation is defined as vdl.WireError; values of E
// type are automatically converted to/from vdl.WireError by VDL and VOM.
type E struct {
	ID         ID            // The identity of the error.
	Action     ActionCode    // Default action to take on error.
	Msg        string        // Error message; empty if no language known.
	ParamList  []interface{} // The variadic parameters given to ExplicitNew().
	stackPCs   []uintptr     // PCs of creators of E
	chainedPCs []uintptr     // PCs of a chained E
}

// TypeOf(verror.E{}) should give vdl.WireError.
func (E) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/vdl.WireError"`
}) {
}

func (x E) VDLEqual(yiface interface{}) bool {
	y := yiface.(E)
	switch {
	case x.ID != y.ID:
		return false
	case x.Action != y.Action:
		return false
	case x.Error() != y.Error():
		// NOTE: We compare the result of Error() rather than comparing the Msg
		// fields, since the Msg field isn't always set; Msg=="" is equivalent to
		// Msg==v.io/v23/verror.Unknown.
		//
		// TODO(toddw): Investigate the root cause of this.
		return false
	case len(x.ParamList) != len(y.ParamList):
		return false
	}
	for i := range x.ParamList {
		if !vdl.DeepEqual(x.ParamList[i], y.ParamList[i]) {
			return false
		}
	}
	return true
}

func (x E) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf(vdl.WireError{})); err != nil {
		return err
	}
	if x.ID != "" {
		if err := enc.NextField("Id"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(string(x.ID)); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Action != NoRetry {
		var actionStr string
		switch x.Action {
		case RetryConnection:
			actionStr = "RetryConnection"
		case RetryRefetch:
			actionStr = "RetryRefetch"
		case RetryBackoff:
			actionStr = "RetryBackoff"
		default:
			return fmt.Errorf("%d does not correspond to a label in enum WireRetryCode", x.Action)
		}
		if err := enc.NextField("RetryCode"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf(vdl.WireRetryCodeNoRetry)); err != nil {
			return err
		}
		if err := enc.EncodeString(actionStr); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Msg != "" {
		if err := enc.NextField("Msg"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Msg); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.ParamList) != 0 {
		if err := enc.NextField("ParamList"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*[]*vdl.Value)(nil))); err != nil {
			return err
		}
		if err := enc.SetLenHint(len(x.ParamList)); err != nil {
			return err
		}
		for i := 0; i < len(x.ParamList); i++ {
			if err := enc.NextEntry(false); err != nil {
				return err
			}
			if x.ParamList[i] == nil {
				if err := enc.NilValue(vdl.AnyType); err != nil {
					return err
				}
			} else {
				if err := vdl.Write(enc, x.ParamList[i]); err != nil {
					return err
				}
			}
		}
		if err := enc.NextEntry(true); 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 *E) VDLRead(dec vdl.Decoder) error {
	*x = E{}
	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
		}
	switchBlock:
		switch f {
		case "":
			return dec.FinishValue()
		case "Id":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if id, err := dec.DecodeString(); err != nil {
				return err
			} else {
				x.ID = ID(id)
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "RetryCode":
			if err := dec.StartValue(); err != nil {
				return err
			}
			label, err := dec.DecodeString()
			if err != nil {
				return err
			}
			switch label {
			case "NoRetry":
				x.Action = NoRetry
			case "RetryConnection":
				x.Action = RetryConnection
			case "RetryRefetch":
				x.Action = RetryRefetch
			case "RetryBackoff":
				x.Action = RetryBackoff
			default:
				return fmt.Errorf("label %s not in enum WireRetryCode", label)
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Msg":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Msg, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "ParamList":
			if err := dec.StartValue(); err != nil {
				return err
			}
			if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x.ParamList), dec.Type()) {
				return fmt.Errorf("incompatible list %T, from %v", x.ParamList, dec.Type())
			}
			switch len := dec.LenHint(); {
			case len > 0:
				x.ParamList = make([]interface{}, 0, len)
			default:
				x.ParamList = nil
			}
			for {
				switch done, err := dec.NextEntry(); {
				case err != nil:
					return err
				case done:
					if err := dec.FinishValue(); err != nil {
						return err
					}
					break switchBlock
				}
				var elem interface{}
				if err := vdl.Read(dec, &elem); err != nil {
					return err
				}
				x.ParamList = append(x.ParamList, elem)
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

const maxPCs = 40 // Maximum number of PC values we'll include in a stack trace.

// A SubErrs is a special type that allows clients to include a list of
// subordinate errors to an error's parameter list.  Clients can add a SubErrs
// to the parameter list directly, via New() of include one in an existing
// error using AddSubErrs().  Each element of the slice has a name, an error,
// and an integer that encodes options such as verror.Print as bits set within
// it.  By convention, clients are expected to use name of the form "X=Y" to
// distinguish their subordinate errors from those of other abstraction layers.
// For example, a layer reporting on errors in individual blessings in an RPC
// might use strings like "blessing=<blessing_name>".
type SubErrs []SubErr

type SubErrOpts uint32

// A SubErr represents a (string, error, int32) triple,  It is the element type for SubErrs.
type SubErr struct {
	Name    string
	Err     error
	Options SubErrOpts
}

const (
	// Print, when set in SubErr.Options, tells Error() to print this SubErr.
	Print SubErrOpts = 0x1
)

func assertIsE(err error) (E, bool) {
	if e, ok := err.(E); ok {
		return e, true
	}
	if e, ok := err.(*E); ok && e != nil {
		return *e, true
	}
	return E{}, false
}

// ErrorID returns the ID of the given err, or Unknown if the err has no ID.
// If err is nil then ErrorID returns "".
func ErrorID(err error) ID {
	if err == nil {
		return ""
	}
	if e, ok := assertIsE(err); ok {
		return e.ID
	}
	return ErrUnknown.ID
}

// Action returns the action of the given err, or NoRetry if the err has no Action.
func Action(err error) ActionCode {
	if err == nil {
		return NoRetry
	}
	if e, ok := assertIsE(err); ok {
		return e.Action
	}
	return NoRetry
}

// PCs represents a list of PC locations
type PCs []uintptr

// Stack returns the list of PC locations on the stack when this error was
// first generated within this address space, or an empty list if err is not an
// E.
func Stack(err error) PCs {
	if err != nil {
		if e, ok := assertIsE(err); ok {
			stackIntPtr := make([]uintptr, len(e.stackPCs))
			copy(stackIntPtr, e.stackPCs)
			if e.chainedPCs != nil {
				stackIntPtr = append(stackIntPtr, uintptr(0))
				stackIntPtr = append(stackIntPtr, e.chainedPCs...)
			}
			return stackIntPtr
		}
	}
	return nil
}

func (st PCs) String() string {
	buf := bytes.NewBufferString("")
	StackToText(buf, st)
	return buf.String()
}

// stackToTextIndent emits on w a text representation of stack, which is typically
// obtained from Stack() and represents the source location(s) where an
// error was generated or passed through in the local address space.
// indent is added to a prefix of each line printed.
func stackToTextIndent(w io.Writer, stack []uintptr, indent string) (err error) {
	for i := 0; i != len(stack) && err == nil; i++ {
		if stack[i] == 0 {
			_, err = fmt.Fprintf(w, "%s----- chained verror -----\n", indent)
		} else {
			fnc := runtime.FuncForPC(stack[i])
			file, line := fnc.FileLine(stack[i])
			_, err = fmt.Fprintf(w, "%s%s:%d: %s\n", indent, file, line, fnc.Name())
		}
	}
	return err
}

// StackToText emits on w a text representation of stack, which is typically
// obtained from Stack() and represents the source location(s) where an
// error was generated or passed through in the local address space.
func StackToText(w io.Writer, stack []uintptr) error {
	return stackToTextIndent(w, stack, "")
}

// defaultLangID returns langID is it is not i18n.NoLangID, and the default
// value of US English otherwise.
func defaultLangID(langID i18n.LangID) i18n.LangID {
	if langID == i18n.NoLangID {
		langID = "en-US"
	}
	return langID
}

func isDefaultIDAction(id ID, action ActionCode) bool {
	return id == "" && action == 0
}

// makeInternal is like ExplicitNew(), but takes a slice of PC values as an argument,
// rather than constructing one from the caller's PC.
func makeInternal(idAction IDAction, langID i18n.LangID, componentName string, opName string, stack []uintptr, v ...interface{}) E {
	msg := ""
	var chainedPCs []uintptr
	for _, par := range v {
		if err, ok := par.(error); ok {
			if _, ok := assertIsE(err); ok {
				chainedPCs = Stack(err)
				break
			}
		}
	}
	params := append([]interface{}{componentName, opName}, v...)
	if langID != i18n.NoLangID {
		id := idAction.ID
		if id == "" {
			id = ErrUnknown.ID
		}
		msg = i18n.Cat().Format(langID, i18n.MsgID(id), params...)
	}
	return E{idAction.ID, idAction.Action, msg, params, stack, chainedPCs}
}

// ExplicitNew returns an error with the given ID, with an error string in the chosen
// language.  The component and operation name are included the first and second
// parameters of the error.  Other parameters are taken from v[].  The
// parameters are formatted into the message according to i18n.Cat().Format.
// The caller's PC is added to the error's stack.
// If the parameter list contains an instance of verror.E, then the stack of
// the first, and only the first, occurrence of such an instance, will be chained
// to the stack of this newly created error.
func ExplicitNew(idAction IDAction, langID i18n.LangID, componentName string, opName string, v ...interface{}) error {
	stack := make([]uintptr, maxPCs)
	stack = stack[:runtime.Callers(2, stack)]
	return makeInternal(idAction, langID, componentName, opName, stack, v...)
}

// A componentKey is used as a key for context.T's Value() map.
type componentKey struct{}

// WithComponentName returns a context based on ctx that has the
// componentName that New() and Convert() can use.
func WithComponentName(ctx *context.T, componentName string) *context.T {
	return context.WithValue(ctx, componentKey{}, componentName)
}

// New is like ExplicitNew(), but obtains the language, component name, and operation
// name from the specified context.T.  ctx may be nil.
func New(idAction IDAction, ctx *context.T, v ...interface{}) error {
	langID, componentName, opName := dataFromContext(ctx)
	stack := make([]uintptr, maxPCs)
	stack = stack[:runtime.Callers(2, stack)]
	return makeInternal(idAction, langID, componentName, opName, stack, v...)
}

// isEmptyString() returns whether v is an empty string.
func isEmptyString(v interface{}) bool {
	str, isAString := v.(string)
	return isAString && str == ""
}

// convertInternal is like ExplicitConvert(), but takes a slice of PC values as an argument,
// rather than constructing one from the caller's PC.
func convertInternal(idAction IDAction, langID i18n.LangID, componentName string, opName string, stack []uintptr, err error) E {
	// If err is already a verror.E, we wish to:
	//  - retain all set parameters.
	//  - if not yet set, set parameters 0 and 1 from componentName and
	//    opName.
	//  - if langID is set, and we have the appropriate language's format
	//    in our catalogue, use it.  Otherwise, retain a message (assuming
	//    additional parameters were not set) even if the language is not
	//    correct.
	if e, ok := assertIsE(err); !ok {
		return makeInternal(idAction, langID, componentName, opName, stack, err.Error())
	} else {
		oldParams := e.ParamList

		// Convert all embedded E errors, recursively.
		for i := range oldParams {
			if subErr, isE := oldParams[i].(E); isE {
				oldParams[i] = convertInternal(idAction, langID, componentName, opName, stack, subErr)
			} else if subErrs, isSubErrs := oldParams[i].(SubErrs); isSubErrs {
				for j := range subErrs {
					if subErr, isE := subErrs[j].Err.(E); isE {
						subErrs[j].Err = convertInternal(idAction, langID, componentName, opName, stack, subErr)
					}
				}
				oldParams[i] = subErrs
			}
		}

		// Create a non-empty format string if we have the language in the catalogue.
		var formatStr string
		if langID != i18n.NoLangID {
			id := e.ID
			if id == "" {
				id = ErrUnknown.ID
			}
			formatStr = i18n.Cat().Lookup(langID, i18n.MsgID(id))
		}

		// Ignore the caller-supplied component and operation if we already have them.
		if componentName != "" && len(oldParams) >= 1 && !isEmptyString(oldParams[0]) {
			componentName = ""
		}
		if opName != "" && len(oldParams) >= 2 && !isEmptyString(oldParams[1]) {
			opName = ""
		}

		var msg string
		var newParams []interface{}
		if componentName == "" && opName == "" {
			if formatStr == "" {
				return e // Nothing to change.
			} else { // Parameter list does not change.
				newParams = e.ParamList
				msg = i18n.FormatParams(formatStr, newParams...)
			}
		} else { // Replace at least one of the first two parameters.
			newLen := len(oldParams)
			if newLen < 2 {
				newLen = 2
			}
			newParams = make([]interface{}, newLen)
			copy(newParams, oldParams)
			if componentName != "" {
				newParams[0] = componentName
			}
			if opName != "" {
				newParams[1] = opName
			}
			if formatStr != "" {
				msg = i18n.FormatParams(formatStr, newParams...)
			}
		}
		return E{e.ID, e.Action, msg, newParams, e.stackPCs, nil}
	}
}

// ExplicitConvert converts a regular err into an E error, setting its IDAction to idAction.  If
// err is already an E, it returns err or an equivalent value without changing its type, but
// potentially changing the language, component or operation if langID!=i18n.NoLangID,
// componentName!="" or opName!="" respectively.  The caller's PC is added to the
// error's stack.
func ExplicitConvert(idAction IDAction, langID i18n.LangID, componentName string, opName string, err error) error {
	if err == nil {
		return nil
	} else {
		var stack []uintptr
		if _, isE := assertIsE(err); !isE { // Walk the stack only if convertInternal will allocate an E.
			stack = make([]uintptr, maxPCs)
			stack = stack[:runtime.Callers(2, stack)]
		}
		return convertInternal(idAction, langID, componentName, opName, stack, err)
	}
}

// defaultCtx is the context used when a nil context.T is passed to New() or Convert().
var (
	defaultCtx     *context.T
	defaultCtxLock sync.RWMutex // Protects defaultCtx.
)

// SetDefaultContext sets the default context used when a nil context.T is
// passed to New() or Convert().  It is typically used in standalone
// programmes that have no RPC context, or in servers for the context of
// ancillary threads not associated with any particular RPC.
func SetDefaultContext(ctx *context.T) {
	defaultCtxLock.Lock()
	defaultCtx = ctx
	defaultCtxLock.Unlock()
}

// Convert is like ExplicitConvert(), but obtains the language, component and operation names
// from the specified context.T.  ctx may be nil.
func Convert(idAction IDAction, ctx *context.T, err error) error {
	if err == nil {
		return nil
	}
	langID, componentName, opName := dataFromContext(ctx)
	var stack []uintptr
	if _, isE := assertIsE(err); !isE { // Walk the stack only if convertInternal will allocate an E.
		stack = make([]uintptr, maxPCs)
		stack = stack[:runtime.Callers(2, stack)]
	}
	return convertInternal(idAction, langID, componentName, opName, stack, err)
}

// dataFromContext reads the languageID, component name, and operation name
// from the context, using defaults as appropriate.
func dataFromContext(ctx *context.T) (langID i18n.LangID, componentName string, opName string) {
	// Use a default context if ctx is nil.  defaultCtx may also be nil, so
	// further nil checks are required below.
	if ctx == nil {
		defaultCtxLock.RLock()
		ctx = defaultCtx
		defaultCtxLock.RUnlock()
	}
	if ctx != nil {
		langID = i18n.GetLangID(ctx)
		value := ctx.Value(componentKey{})
		componentName, _ = value.(string)
		opName = vtrace.GetSpan(ctx).Name()
	}
	if componentName == "" {
		componentName = filepath.Base(os.Args[0])
	}
	return defaultLangID(langID), componentName, opName
}

// Error returns the error message; if it has not been formatted for a specific
// language, a default message containing the error ID and parameters is
// generated.  This method is required to fulfil the error interface.
func (e E) Error() string {
	msg := e.Msg
	if isDefaultIDAction(e.ID, e.Action) && msg == "" {
		msg = i18n.Cat().Format(i18n.NoLangID, i18n.MsgID(ErrUnknown.ID), e.ParamList...)
	} else if msg == "" {
		msg = i18n.Cat().Format(i18n.NoLangID, i18n.MsgID(e.ID), e.ParamList...)
	}
	return msg
}

// String is the default printing function for SubErrs.
func (subErrs SubErrs) String() (result string) {
	if len(subErrs) > 0 {
		sep := ""
		for _, s := range subErrs {
			if (s.Options & Print) != 0 {
				result += fmt.Sprintf("%s[%s: %s]", sep, s.Name, s.Err.Error())
				sep = ", "
			}
		}
	}
	return result
}

// params returns the variadic arguments to ExplicitNew().  We do not export it
// to discourage its abuse as a general-purpose way to pass alternate return
// values.
func params(err error) []interface{} {
	if e, ok := assertIsE(err); ok {
		return e.ParamList
	}
	return nil
}

// subErrorIndex returns index of the first SubErrs in e.ParamList
// or len(e.ParamList) if there is no such parameter.
func (e E) subErrorIndex() (i int) {
	for i = range e.ParamList {
		if _, isSubErrs := e.ParamList[i].(SubErrs); isSubErrs {
			return i
		}
	}
	return len(e.ParamList)
}

// subErrors returns a copy of the subordinate errors accumulated into err, or
// nil if there are no such errors.  We do not export it to discourage its
// abuse as a general-purpose way to pass alternate return values.
func subErrors(err error) (r SubErrs) {
	if e, ok := assertIsE(err); ok {
		size := 0
		for i := range e.ParamList {
			if subErrsParam, isSubErrs := e.ParamList[i].(SubErrs); isSubErrs {
				size += len(subErrsParam)
			}
		}
		if size != 0 {
			r = make(SubErrs, 0, size)
			for i := range e.ParamList {
				if subErrsParam, isSubErrs := e.ParamList[i].(SubErrs); isSubErrs {
					r = append(r, subErrsParam...)
				}
			}
		}
	}
	return r
}

// addSubErrsInternal returns a copy of err with supplied errors appended as
// subordinate errors.  Requires that errors[i].Err!=nil for 0<=i<len(errors).
func addSubErrsInternal(err error, langID i18n.LangID, componentName string, opName string, stack []uintptr, errors SubErrs) error {
	var pe *E
	var e E
	var ok bool
	if pe, ok = err.(*E); ok {
		e = *pe
	} else if e, ok = err.(E); !ok {
		panic("non-verror.E passed to verror.AddSubErrs")
	}
	var subErrs SubErrs
	index := e.subErrorIndex()
	copy(e.ParamList, e.ParamList)
	if index == len(e.ParamList) {
		e.ParamList = append(e.ParamList, subErrs)
	} else {
		copy(subErrs, e.ParamList[index].(SubErrs))
	}
	for _, subErr := range errors {
		if _, ok := assertIsE(subErr.Err); ok {
			subErrs = append(subErrs, subErr)
		} else {
			subErr.Err = convertInternal(IDAction{}, langID, componentName, opName, stack, subErr.Err)
			subErrs = append(subErrs, subErr)
		}
	}
	e.ParamList[index] = subErrs
	if langID != i18n.NoLangID {
		e.Msg = i18n.Cat().Format(langID, i18n.MsgID(e.ID), e.ParamList...)
	}
	return e
}

// ExplicitAddSubErrs returns a copy of err with supplied errors appended as
// subordinate errors.  Requires that errors[i].Err!=nil for 0<=i<len(errors).
func ExplicitAddSubErrs(err error, langID i18n.LangID, componentName string, opName string, errors ...SubErr) error {
	stack := make([]uintptr, maxPCs)
	stack = stack[:runtime.Callers(2, stack)]
	return addSubErrsInternal(err, langID, componentName, opName, stack, errors)
}

// AddSubErrs is like ExplicitAddSubErrs, but uses the provided context
// to obtain the langID, componentName, and opName values.
func AddSubErrs(err error, ctx *context.T, errors ...SubErr) error {
	stack := make([]uintptr, maxPCs)
	stack = stack[:runtime.Callers(2, stack)]
	langID, componentName, opName := dataFromContext(ctx)
	return addSubErrsInternal(err, langID, componentName, opName, stack, errors)
}

// debugStringInternal returns a more verbose string representation of an
// error, perhaps more thorough than one might present to an end user, but
// useful for debugging by a developer.  It prefixes all lines output with
// "prefix" and "name" (if non-empty) and adds intent to prefix wen recursing.
func debugStringInternal(err error, prefix string, name string) string {
	str := prefix
	if len(name) > 0 {
		str += name + " "
	}
	str += err.Error()
	// Append err's stack, indented a little.
	prefix += "  "
	buf := bytes.NewBufferString("")
	stackToTextIndent(buf, Stack(err), prefix)
	str += "\n" + buf.String()
	// Print all the subordinate errors, even the ones that were not
	// printed by Error(), indented a bit further.
	prefix += "  "
	if subErrs := subErrors(err); len(subErrs) > 0 {
		for _, s := range subErrs {
			str += debugStringInternal(s.Err, prefix, s.Name)
		}
	}
	return str
}

// DebugString returns a more verbose string representation of an error,
// perhaps more thorough than one might present to an end user, but useful for
// debugging by a developer.
func DebugString(err error) string {
	return debugStringInternal(err, "", "")
}

// ErrorTarget is a vdl.Target that assigns to a go error.
// It differs from vdl.WireErrorTarget because it assigns to a native
// go error rather than a WireError.
type ErrorTarget struct {
	Value *error
	wire  vdl.WireError
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *ErrorTarget) FromNil(tt *vdl.Type) error {
	if !vdl.Compatible(tt, vdl.ErrorType) {
		return fmt.Errorf("Type %v incompatible with expected type %v", tt, vdl.ErrorType)
	}
	*t.Value = nil
	return nil
}
func (t *ErrorTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
	if !vdl.Compatible(tt, vdl.ErrorType) {
		return nil, fmt.Errorf("Type %v incompatible with expected type %v", tt, vdl.ErrorType)
	}
	return t.wire.MakeVDLTarget().StartFields(tt)
}
func (t *ErrorTarget) FinishFields(_ vdl.FieldsTarget) error {
	var e E
	err := WireToNative(t.wire, &e)
	*t.Value = &e
	return err
}
