// 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.
// Source: errors.vdl

package rpc

import (
	// VDL system imports
	"v.io/v23/context"
	"v.io/v23/i18n"
	"v.io/v23/verror"
)

var (
	// Internal errors.
	errBadRequest                    = verror.Register("v.io/x/ref/runtime/internal/rpc.badRequest", verror.NoRetry, "{1:}{2:} failed to decode request: {3}")
	errBadNumInputArgs               = verror.Register("v.io/x/ref/runtime/internal/rpc.badNumInputArgs", verror.NoRetry, "{1:}{2:} wrong number of input arguments for {3}.{4} (called with {5} args, want {6})")
	errBadInputArg                   = verror.Register("v.io/x/ref/runtime/internal/rpc.badInputArg", verror.NoRetry, "{1:}{2:} failed to decode request {3}.{4} arg #{5}: {6}")
	errBadBlessings                  = verror.Register("v.io/x/ref/runtime/internal/rpc.badBlessings", verror.NoRetry, "{1:}{2:} failed to decode blessings: {3}")
	errBadBlessingsCache             = verror.Register("v.io/x/ref/runtime/internal/rpc.badBlessingsCache", verror.NoRetry, "{1:}{2:} failed to find blessings in cache: {3}")
	errBadDischarge                  = verror.Register("v.io/x/ref/runtime/internal/rpc.badDischarge", verror.NoRetry, "{1:}{2:} failed to decode discharge #{3}: {4}")
	errBadAuth                       = verror.Register("v.io/x/ref/runtime/internal/rpc.badAuth", verror.NoRetry, "{1:}{2:} not authorized to call {3}.{4}: {5}")
	errTypeFlowFailure               = verror.Register("v.io/x/ref/runtime/internal/rpc.typeFlowFailure", verror.NoRetry, "{1:}{2:} type flow could not be constructed{:3}")
	errServerBlessingsWrongPublicKey = verror.Register("v.io/x/ref/runtime/internal/rpc.serverBlessingsWrongPublicKey", verror.NoRetry, "{1:}{2:} server blessings do not match the principals public key")
)

func init() {
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errBadRequest.ID), "{1:}{2:} failed to decode request: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errBadNumInputArgs.ID), "{1:}{2:} wrong number of input arguments for {3}.{4} (called with {5} args, want {6})")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errBadInputArg.ID), "{1:}{2:} failed to decode request {3}.{4} arg #{5}: {6}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errBadBlessings.ID), "{1:}{2:} failed to decode blessings: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errBadBlessingsCache.ID), "{1:}{2:} failed to find blessings in cache: {3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errBadDischarge.ID), "{1:}{2:} failed to decode discharge #{3}: {4}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errBadAuth.ID), "{1:}{2:} not authorized to call {3}.{4}: {5}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errTypeFlowFailure.ID), "{1:}{2:} type flow could not be constructed{:3}")
	i18n.Cat().SetWithBase(i18n.LangID("en"), i18n.MsgID(errServerBlessingsWrongPublicKey.ID), "{1:}{2:} server blessings do not match the principals public key")
}

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

// newErrBadNumInputArgs returns an error with the errBadNumInputArgs ID.
func newErrBadNumInputArgs(ctx *context.T, suffix string, method string, numCalled uint64, numWanted uint64) error {
	return verror.New(errBadNumInputArgs, ctx, suffix, method, numCalled, numWanted)
}

// newErrBadInputArg returns an error with the errBadInputArg ID.
func newErrBadInputArg(ctx *context.T, suffix string, method string, index uint64, err error) error {
	return verror.New(errBadInputArg, ctx, suffix, method, index, err)
}

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

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

// newErrBadDischarge returns an error with the errBadDischarge ID.
func newErrBadDischarge(ctx *context.T, index uint64, err error) error {
	return verror.New(errBadDischarge, ctx, index, err)
}

// newErrBadAuth returns an error with the errBadAuth ID.
func newErrBadAuth(ctx *context.T, suffix string, method string, err error) error {
	return verror.New(errBadAuth, ctx, suffix, method, err)
}

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

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