|  | // Copyright 2018 The Go 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 errors implements functions to manipulate errors. | 
|  | package errors | 
|  |  | 
|  | import ( | 
|  | "errors" | 
|  | "fmt" | 
|  |  | 
|  | "google.golang.org/protobuf/internal/detrand" | 
|  | ) | 
|  |  | 
|  | // Error is a sentinel matching all errors produced by this package. | 
|  | var Error = errors.New("protobuf error") | 
|  |  | 
|  | // New formats a string according to the format specifier and arguments and | 
|  | // returns an error that has a "proto" prefix. | 
|  | func New(f string, x ...any) error { | 
|  | return &prefixError{s: format(f, x...)} | 
|  | } | 
|  |  | 
|  | type prefixError struct{ s string } | 
|  |  | 
|  | var prefix = func() string { | 
|  | // Deliberately introduce instability into the error message string to | 
|  | // discourage users from performing error string comparisons. | 
|  | if detrand.Bool() { | 
|  | return "proto: " // use non-breaking spaces (U+00a0) | 
|  | } else { | 
|  | return "proto: " // use regular spaces (U+0020) | 
|  | } | 
|  | }() | 
|  |  | 
|  | func (e *prefixError) Error() string { | 
|  | return prefix + e.s | 
|  | } | 
|  |  | 
|  | func (e *prefixError) Unwrap() error { | 
|  | return Error | 
|  | } | 
|  |  | 
|  | // Wrap returns an error that has a "proto" prefix, the formatted string described | 
|  | // by the format specifier and arguments, and a suffix of err. The error wraps err. | 
|  | func Wrap(err error, f string, x ...any) error { | 
|  | return &wrapError{ | 
|  | s:   format(f, x...), | 
|  | err: err, | 
|  | } | 
|  | } | 
|  |  | 
|  | type wrapError struct { | 
|  | s   string | 
|  | err error | 
|  | } | 
|  |  | 
|  | func (e *wrapError) Error() string { | 
|  | return format("%v%v: %v", prefix, e.s, e.err) | 
|  | } | 
|  |  | 
|  | func (e *wrapError) Unwrap() error { | 
|  | return e.err | 
|  | } | 
|  |  | 
|  | func (e *wrapError) Is(target error) bool { | 
|  | return target == Error | 
|  | } | 
|  |  | 
|  | func format(f string, x ...any) string { | 
|  | // avoid "proto: " prefix when chaining | 
|  | for i := 0; i < len(x); i++ { | 
|  | switch e := x[i].(type) { | 
|  | case *prefixError: | 
|  | x[i] = e.s | 
|  | case *wrapError: | 
|  | x[i] = format("%v: %v", e.s, e.err) | 
|  | } | 
|  | } | 
|  | return fmt.Sprintf(f, x...) | 
|  | } | 
|  |  | 
|  | func InvalidUTF8(name string) error { | 
|  | return New("field %v contains invalid UTF-8", name) | 
|  | } | 
|  |  | 
|  | func RequiredNotSet(name string) error { | 
|  | return New("required field %v not set", name) | 
|  | } | 
|  |  | 
|  | type SizeMismatchError struct { | 
|  | Calculated, Measured int | 
|  | } | 
|  |  | 
|  | func (e *SizeMismatchError) Error() string { | 
|  | return fmt.Sprintf("size mismatch (see https://github.com/golang/protobuf/issues/1609): calculated=%d, measured=%d", e.Calculated, e.Measured) | 
|  | } | 
|  |  | 
|  | func MismatchedSizeCalculation(calculated, measured int) error { | 
|  | return &SizeMismatchError{ | 
|  | Calculated: calculated, | 
|  | Measured:   measured, | 
|  | } | 
|  | } |