peridot/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/errors.go
Mustafa Gezen ad0f7a5305
Major upgrades
Upgrade to Go 1.20.5, Hydra v2 SDK, rules-go v0.44.2 (with proper resolves), protobuf v25.3 and mass upgrade of Go dependencies.
2024-03-17 08:06:08 +01:00

184 lines
4.5 KiB
Go

// Copyright 2020 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 json
import (
"errors"
"reflect"
"strconv"
"strings"
"unicode/utf8"
)
const errorPrefix = "json: "
// Error matches errors returned by this package according to errors.Is.
const Error = jsonError("json error")
type jsonError string
func (e jsonError) Error() string {
return string(e)
}
func (e jsonError) Is(target error) bool {
return e == target || target == Error
}
type ioError struct {
action string // either "read" or "write"
err error
}
func (e *ioError) Error() string {
return errorPrefix + e.action + " error: " + e.err.Error()
}
func (e *ioError) Unwrap() error {
return e.err
}
func (e *ioError) Is(target error) bool {
return e == target || target == Error || errors.Is(e.err, target)
}
// SemanticError describes an error determining the meaning
// of JSON data as Go data or vice-versa.
//
// The contents of this error as produced by this package may change over time.
type SemanticError struct {
requireKeyedLiterals
nonComparable
action string // either "marshal" or "unmarshal"
// ByteOffset indicates that an error occurred after this byte offset.
ByteOffset int64
// JSONPointer indicates that an error occurred within this JSON value
// as indicated using the JSON Pointer notation (see RFC 6901).
JSONPointer string
// JSONKind is the JSON kind that could not be handled.
JSONKind Kind // may be zero if unknown
// GoType is the Go type that could not be handled.
GoType reflect.Type // may be nil if unknown
// Err is the underlying error.
Err error // may be nil
}
func (e *SemanticError) Error() string {
var sb strings.Builder
sb.WriteString(errorPrefix)
// Hyrum-proof the error message by deliberately switching between
// two equivalent renderings of the same error message.
// The randomization is tied to the Hyrum-proofing already applied
// on map iteration in Go.
for phrase := range map[string]struct{}{"cannot": {}, "unable to": {}} {
sb.WriteString(phrase)
break // use whichever phrase we get in the first iteration
}
// Format action.
var preposition string
switch e.action {
case "marshal":
sb.WriteString(" marshal")
preposition = " from"
case "unmarshal":
sb.WriteString(" unmarshal")
preposition = " into"
default:
sb.WriteString(" handle")
preposition = " with"
}
// Format JSON kind.
var omitPreposition bool
switch e.JSONKind {
case 'n':
sb.WriteString(" JSON null")
case 'f', 't':
sb.WriteString(" JSON boolean")
case '"':
sb.WriteString(" JSON string")
case '0':
sb.WriteString(" JSON number")
case '{', '}':
sb.WriteString(" JSON object")
case '[', ']':
sb.WriteString(" JSON array")
default:
omitPreposition = true
}
// Format Go type.
if e.GoType != nil {
if !omitPreposition {
sb.WriteString(preposition)
}
sb.WriteString(" Go value of type ")
sb.WriteString(e.GoType.String())
}
// Format where.
switch {
case e.JSONPointer != "":
sb.WriteString(" within JSON value at ")
sb.WriteString(strconv.Quote(e.JSONPointer))
case e.ByteOffset > 0:
sb.WriteString(" after byte offset ")
sb.WriteString(strconv.FormatInt(e.ByteOffset, 10))
}
// Format underlying error.
if e.Err != nil {
sb.WriteString(": ")
sb.WriteString(e.Err.Error())
}
return sb.String()
}
func (e *SemanticError) Is(target error) bool {
return e == target || target == Error || errors.Is(e.Err, target)
}
func (e *SemanticError) Unwrap() error {
return e.Err
}
// SyntacticError is a description of a syntactic error that occurred when
// encoding or decoding JSON according to the grammar.
//
// The contents of this error as produced by this package may change over time.
type SyntacticError struct {
requireKeyedLiterals
nonComparable
// ByteOffset indicates that an error occurred after this byte offset.
ByteOffset int64
str string
}
func (e *SyntacticError) Error() string {
return errorPrefix + e.str
}
func (e *SyntacticError) Is(target error) bool {
return e == target || target == Error
}
func (e *SyntacticError) withOffset(pos int64) error {
return &SyntacticError{ByteOffset: pos, str: e.str}
}
func newInvalidCharacterError(prefix []byte, where string) *SyntacticError {
what := quoteRune(prefix)
return &SyntacticError{str: "invalid character " + what + " " + where}
}
func quoteRune(b []byte) string {
r, n := utf8.DecodeRune(b)
if r == utf8.RuneError && n == 1 {
return `'\x` + strconv.FormatUint(uint64(b[0]), 16) + `'`
}
return strconv.QuoteRune(r)
}