func Define(name, messageFormat string, publicAttributes ...string) *Definition {
	return define(uint32(codes.Unknown), name, messageFormat, publicAttributes...)
}
Define defines a registered error of type Unknown.
package errors
import (
	"fmt"
	"regexp"
	"github.com/gotnospirit/messageformat"
	"go.thethings.network/lorawan-stack/v3/pkg/i18n"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)
type Definition struct {
	namespace              string
	name                   string
	messageFormat          string
	messageFormatArguments []string
	parsedMessageFormat    *messageformat.MessageFormat
	publicAttributes       []string
	code                   uint32  
	grpcStatus             *status.Status
}
type DefinitionInterface interface {
	error
	fmt.Stringer
	Namespace() string
	Name() string
	FullName() string
	MessageFormat() string
	Code() uint32
}
func (d *Definition) Namespace() string {
	if d == nil {
		return ""
	}
	return d.namespace
}
func (d *Definition) Name() string {
	if d == nil {
		return ""
	}
	return d.name
}
func (d *Definition) FullName() string {
	if d == nil {
		return ""
	}
	namespace := d.namespace
	if namespace == "" {
		namespace = "unknown"
	}
	name := d.name
	if name == "" {
		name = "unknown"
	}
	return fmt.Sprintf("%s:%s", namespace, name)
}
func (d *Definition) MessageFormat() string {
	if d == nil {
		return ""
	}
	return d.messageFormat
}
func (d *Definition) Code() uint32 {
	if d == nil {
		return 0
	}
	return d.code
}
func (d *Definition) String() string {
	if d == nil {
		return ""
	}
	return fmt.Sprintf("error:%s (%s)", d.FullName(), d.messageFormat)
}
func (d *Definition) Error() string {
	if d == nil {
		return ""
	}
	return d.String()
}
var messageFormatArgument = regexp.MustCompile(`\{[\s]*([a-z0-9_]+)`)
func messageFormatArguments(messageFormat string) (args []string) {
	for _, matches := range messageFormatArgument.FindAllStringSubmatch(messageFormat, -1) {
		if len(matches) == 2 {
			args = append(args, matches[1])
		}
	}
	m := make(map[string]struct{}, len(args))
	for _, arg := range args {
		m[arg] = struct{}{}
	}
	args = make([]string, 0, len(m))
	for arg := range m {
		args = append(args, arg)
	}
	return
}
func define(code uint32, name, messageFormat string, publicAttributes ...string) *Definition {
	ns := namespace(3)
	if code == 0 {
		code = uint32(codes.Unknown)
	}
	def := Definition{
		namespace:              ns,
		name:                   name,
		messageFormat:          messageFormat,
		messageFormatArguments: messageFormatArguments(messageFormat),
		publicAttributes:       publicAttributes,
		code:                   code,
	}
	fullName := def.FullName()
	if Definitions[fullName] != nil {
		panic(fmt.Errorf("error %s already defined", fullName))
	}
	parsedMessageFormat, err := formatter.Parse(messageFormat)
	if err != nil {
		panic(fmt.Errorf("could not parse message format `%s` for %s: %s", messageFormat, fullName, err))
	}
	def.parsedMessageFormat = parsedMessageFormat
nextArg:
	for _, arg := range def.messageFormatArguments {
		for _, attr := range def.publicAttributes {
			if arg == attr {
				continue nextArg
			}
		}
		def.publicAttributes = append(def.publicAttributes, arg)
	}
	def.setGRPCStatus()  
	Definitions[fullName] = &def
	desc := i18n.Define(fmt.Sprintf("error:%s", fullName), def.messageFormat)
	desc.SetSource(2)
	return &def
}
var Definitions = make(map[string]*Definition)