mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	vendor: bump k8s to v0.25.4
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										1437
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1437
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1419
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1419
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										143
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
// Copyright 2013 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 (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	caseMask     = ^byte(0x20) // Mask to ignore case in ASCII.
 | 
			
		||||
	kelvin       = '\u212a'
 | 
			
		||||
	smallLongEss = '\u017f'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// foldFunc returns one of four different case folding equivalence
 | 
			
		||||
// functions, from most general (and slow) to fastest:
 | 
			
		||||
//
 | 
			
		||||
// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
 | 
			
		||||
// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
 | 
			
		||||
// 3) asciiEqualFold, no special, but includes non-letters (including _)
 | 
			
		||||
// 4) simpleLetterEqualFold, no specials, no non-letters.
 | 
			
		||||
//
 | 
			
		||||
// The letters S and K are special because they map to 3 runes, not just 2:
 | 
			
		||||
//  * S maps to s and to U+017F 'ſ' Latin small letter long s
 | 
			
		||||
//  * k maps to K and to U+212A 'K' Kelvin sign
 | 
			
		||||
// See https://play.golang.org/p/tTxjOc0OGo
 | 
			
		||||
//
 | 
			
		||||
// The returned function is specialized for matching against s and
 | 
			
		||||
// should only be given s. It's not curried for performance reasons.
 | 
			
		||||
func foldFunc(s []byte) func(s, t []byte) bool {
 | 
			
		||||
	nonLetter := false
 | 
			
		||||
	special := false // special letter
 | 
			
		||||
	for _, b := range s {
 | 
			
		||||
		if b >= utf8.RuneSelf {
 | 
			
		||||
			return bytes.EqualFold
 | 
			
		||||
		}
 | 
			
		||||
		upper := b & caseMask
 | 
			
		||||
		if upper < 'A' || upper > 'Z' {
 | 
			
		||||
			nonLetter = true
 | 
			
		||||
		} else if upper == 'K' || upper == 'S' {
 | 
			
		||||
			// See above for why these letters are special.
 | 
			
		||||
			special = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if special {
 | 
			
		||||
		return equalFoldRight
 | 
			
		||||
	}
 | 
			
		||||
	if nonLetter {
 | 
			
		||||
		return asciiEqualFold
 | 
			
		||||
	}
 | 
			
		||||
	return simpleLetterEqualFold
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// equalFoldRight is a specialization of bytes.EqualFold when s is
 | 
			
		||||
// known to be all ASCII (including punctuation), but contains an 's',
 | 
			
		||||
// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
 | 
			
		||||
// See comments on foldFunc.
 | 
			
		||||
func equalFoldRight(s, t []byte) bool {
 | 
			
		||||
	for _, sb := range s {
 | 
			
		||||
		if len(t) == 0 {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		tb := t[0]
 | 
			
		||||
		if tb < utf8.RuneSelf {
 | 
			
		||||
			if sb != tb {
 | 
			
		||||
				sbUpper := sb & caseMask
 | 
			
		||||
				if 'A' <= sbUpper && sbUpper <= 'Z' {
 | 
			
		||||
					if sbUpper != tb&caseMask {
 | 
			
		||||
						return false
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					return false
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			t = t[1:]
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// sb is ASCII and t is not. t must be either kelvin
 | 
			
		||||
		// sign or long s; sb must be s, S, k, or K.
 | 
			
		||||
		tr, size := utf8.DecodeRune(t)
 | 
			
		||||
		switch sb {
 | 
			
		||||
		case 's', 'S':
 | 
			
		||||
			if tr != smallLongEss {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		case 'k', 'K':
 | 
			
		||||
			if tr != kelvin {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		t = t[size:]
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	if len(t) > 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// asciiEqualFold is a specialization of bytes.EqualFold for use when
 | 
			
		||||
// s is all ASCII (but may contain non-letters) and contains no
 | 
			
		||||
// special-folding letters.
 | 
			
		||||
// See comments on foldFunc.
 | 
			
		||||
func asciiEqualFold(s, t []byte) bool {
 | 
			
		||||
	if len(s) != len(t) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i, sb := range s {
 | 
			
		||||
		tb := t[i]
 | 
			
		||||
		if sb == tb {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
 | 
			
		||||
			if sb&caseMask != tb&caseMask {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// simpleLetterEqualFold is a specialization of bytes.EqualFold for
 | 
			
		||||
// use when s is all ASCII letters (no underscores, etc) and also
 | 
			
		||||
// doesn't contain 'k', 'K', 's', or 'S'.
 | 
			
		||||
// See comments on foldFunc.
 | 
			
		||||
func simpleLetterEqualFold(s, t []byte) bool {
 | 
			
		||||
	if len(s) != len(t) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i, b := range s {
 | 
			
		||||
		if b&caseMask != t[i]&caseMask {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// Copyright 2019 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.
 | 
			
		||||
 | 
			
		||||
//go:build gofuzz
 | 
			
		||||
 | 
			
		||||
package json
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Fuzz(data []byte) (score int) {
 | 
			
		||||
	for _, ctor := range []func() any{
 | 
			
		||||
		func() any { return new(any) },
 | 
			
		||||
		func() any { return new(map[string]any) },
 | 
			
		||||
		func() any { return new([]any) },
 | 
			
		||||
	} {
 | 
			
		||||
		v := ctor()
 | 
			
		||||
		err := Unmarshal(data, v)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		score = 1
 | 
			
		||||
 | 
			
		||||
		m, err := Marshal(v)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Printf("v=%#v\n", v)
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		u := ctor()
 | 
			
		||||
		err = Unmarshal(m, u)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Printf("v=%#v\n", v)
 | 
			
		||||
			fmt.Printf("m=%s\n", m)
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										143
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/indent.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/indent.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
// Copyright 2010 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 (
 | 
			
		||||
	"bytes"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Compact appends to dst the JSON-encoded src with
 | 
			
		||||
// insignificant space characters elided.
 | 
			
		||||
func Compact(dst *bytes.Buffer, src []byte) error {
 | 
			
		||||
	return compact(dst, src, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func compact(dst *bytes.Buffer, src []byte, escape bool) error {
 | 
			
		||||
	origLen := dst.Len()
 | 
			
		||||
	scan := newScanner()
 | 
			
		||||
	defer freeScanner(scan)
 | 
			
		||||
	start := 0
 | 
			
		||||
	for i, c := range src {
 | 
			
		||||
		if escape && (c == '<' || c == '>' || c == '&') {
 | 
			
		||||
			if start < i {
 | 
			
		||||
				dst.Write(src[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			dst.WriteString(`\u00`)
 | 
			
		||||
			dst.WriteByte(hex[c>>4])
 | 
			
		||||
			dst.WriteByte(hex[c&0xF])
 | 
			
		||||
			start = i + 1
 | 
			
		||||
		}
 | 
			
		||||
		// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
 | 
			
		||||
		if escape && c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
 | 
			
		||||
			if start < i {
 | 
			
		||||
				dst.Write(src[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			dst.WriteString(`\u202`)
 | 
			
		||||
			dst.WriteByte(hex[src[i+2]&0xF])
 | 
			
		||||
			start = i + 3
 | 
			
		||||
		}
 | 
			
		||||
		v := scan.step(scan, c)
 | 
			
		||||
		if v >= scanSkipSpace {
 | 
			
		||||
			if v == scanError {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			if start < i {
 | 
			
		||||
				dst.Write(src[start:i])
 | 
			
		||||
			}
 | 
			
		||||
			start = i + 1
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if scan.eof() == scanError {
 | 
			
		||||
		dst.Truncate(origLen)
 | 
			
		||||
		return scan.err
 | 
			
		||||
	}
 | 
			
		||||
	if start < len(src) {
 | 
			
		||||
		dst.Write(src[start:])
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newline(dst *bytes.Buffer, prefix, indent string, depth int) {
 | 
			
		||||
	dst.WriteByte('\n')
 | 
			
		||||
	dst.WriteString(prefix)
 | 
			
		||||
	for i := 0; i < depth; i++ {
 | 
			
		||||
		dst.WriteString(indent)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Indent appends to dst an indented form of the JSON-encoded src.
 | 
			
		||||
// Each element in a JSON object or array begins on a new,
 | 
			
		||||
// indented line beginning with prefix followed by one or more
 | 
			
		||||
// copies of indent according to the indentation nesting.
 | 
			
		||||
// The data appended to dst does not begin with the prefix nor
 | 
			
		||||
// any indentation, to make it easier to embed inside other formatted JSON data.
 | 
			
		||||
// Although leading space characters (space, tab, carriage return, newline)
 | 
			
		||||
// at the beginning of src are dropped, trailing space characters
 | 
			
		||||
// at the end of src are preserved and copied to dst.
 | 
			
		||||
// For example, if src has no trailing spaces, neither will dst;
 | 
			
		||||
// if src ends in a trailing newline, so will dst.
 | 
			
		||||
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
 | 
			
		||||
	origLen := dst.Len()
 | 
			
		||||
	scan := newScanner()
 | 
			
		||||
	defer freeScanner(scan)
 | 
			
		||||
	needIndent := false
 | 
			
		||||
	depth := 0
 | 
			
		||||
	for _, c := range src {
 | 
			
		||||
		scan.bytes++
 | 
			
		||||
		v := scan.step(scan, c)
 | 
			
		||||
		if v == scanSkipSpace {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if v == scanError {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if needIndent && v != scanEndObject && v != scanEndArray {
 | 
			
		||||
			needIndent = false
 | 
			
		||||
			depth++
 | 
			
		||||
			newline(dst, prefix, indent, depth)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Emit semantically uninteresting bytes
 | 
			
		||||
		// (in particular, punctuation in strings) unmodified.
 | 
			
		||||
		if v == scanContinue {
 | 
			
		||||
			dst.WriteByte(c)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Add spacing around real punctuation.
 | 
			
		||||
		switch c {
 | 
			
		||||
		case '{', '[':
 | 
			
		||||
			// delay indent so that empty object and array are formatted as {} and [].
 | 
			
		||||
			needIndent = true
 | 
			
		||||
			dst.WriteByte(c)
 | 
			
		||||
 | 
			
		||||
		case ',':
 | 
			
		||||
			dst.WriteByte(c)
 | 
			
		||||
			newline(dst, prefix, indent, depth)
 | 
			
		||||
 | 
			
		||||
		case ':':
 | 
			
		||||
			dst.WriteByte(c)
 | 
			
		||||
			dst.WriteByte(' ')
 | 
			
		||||
 | 
			
		||||
		case '}', ']':
 | 
			
		||||
			if needIndent {
 | 
			
		||||
				// suppress indent in empty object/array
 | 
			
		||||
				needIndent = false
 | 
			
		||||
			} else {
 | 
			
		||||
				depth--
 | 
			
		||||
				newline(dst, prefix, indent, depth)
 | 
			
		||||
			}
 | 
			
		||||
			dst.WriteByte(c)
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			dst.WriteByte(c)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if scan.eof() == scanError {
 | 
			
		||||
		dst.Truncate(origLen)
 | 
			
		||||
		return scan.err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										168
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/kubernetes_patch.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/kubernetes_patch.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2021 The Kubernetes Authors.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package json
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	gojson "encoding/json"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Type-alias error and data types returned from decoding
 | 
			
		||||
 | 
			
		||||
type UnmarshalTypeError = gojson.UnmarshalTypeError
 | 
			
		||||
type UnmarshalFieldError = gojson.UnmarshalFieldError
 | 
			
		||||
type InvalidUnmarshalError = gojson.InvalidUnmarshalError
 | 
			
		||||
type Number = gojson.Number
 | 
			
		||||
type RawMessage = gojson.RawMessage
 | 
			
		||||
type Token = gojson.Token
 | 
			
		||||
type Delim = gojson.Delim
 | 
			
		||||
 | 
			
		||||
type UnmarshalOpt func(*decodeState)
 | 
			
		||||
 | 
			
		||||
func UseNumber(d *decodeState) {
 | 
			
		||||
	d.useNumber = true
 | 
			
		||||
}
 | 
			
		||||
func DisallowUnknownFields(d *decodeState) {
 | 
			
		||||
	d.disallowUnknownFields = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CaseSensitive requires json keys to exactly match specified json tags (for tagged struct fields)
 | 
			
		||||
// or struct field names (for untagged struct fields), or be treated as an unknown field.
 | 
			
		||||
func CaseSensitive(d *decodeState) {
 | 
			
		||||
	d.caseSensitive = true
 | 
			
		||||
}
 | 
			
		||||
func (d *Decoder) CaseSensitive() {
 | 
			
		||||
	d.d.caseSensitive = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PreserveInts decodes numbers as int64 when decoding to untyped fields,
 | 
			
		||||
// if the JSON data does not contain a "." character, parses as an integer successfully,
 | 
			
		||||
// and does not overflow int64. Otherwise, it falls back to default float64 decoding behavior.
 | 
			
		||||
//
 | 
			
		||||
// If UseNumber is also set, it takes precedence over PreserveInts.
 | 
			
		||||
func PreserveInts(d *decodeState) {
 | 
			
		||||
	d.preserveInts = true
 | 
			
		||||
}
 | 
			
		||||
func (d *Decoder) PreserveInts() {
 | 
			
		||||
	d.d.preserveInts = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DisallowDuplicateFields treats duplicate fields encountered while decoding as an error.
 | 
			
		||||
func DisallowDuplicateFields(d *decodeState) {
 | 
			
		||||
	d.disallowDuplicateFields = true
 | 
			
		||||
}
 | 
			
		||||
func (d *Decoder) DisallowDuplicateFields() {
 | 
			
		||||
	d.d.disallowDuplicateFields = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *decodeState) newFieldError(errType strictErrType, field string) *strictError {
 | 
			
		||||
	if len(d.strictFieldStack) > 0 {
 | 
			
		||||
		return &strictError{
 | 
			
		||||
			ErrType: errType,
 | 
			
		||||
			Path:    strings.Join(d.strictFieldStack, "") + "." + field,
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		return &strictError{
 | 
			
		||||
			ErrType: errType,
 | 
			
		||||
			Path:    field,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// saveStrictError saves a strict decoding error,
 | 
			
		||||
// for reporting at the end of the unmarshal if no other errors occurred.
 | 
			
		||||
func (d *decodeState) saveStrictError(err *strictError) {
 | 
			
		||||
	// prevent excessive numbers of accumulated errors
 | 
			
		||||
	if len(d.savedStrictErrors) >= 100 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// dedupe accumulated strict errors
 | 
			
		||||
	if d.seenStrictErrors == nil {
 | 
			
		||||
		d.seenStrictErrors = map[strictError]struct{}{}
 | 
			
		||||
	}
 | 
			
		||||
	if _, seen := d.seenStrictErrors[*err]; seen {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// accumulate the error
 | 
			
		||||
	d.seenStrictErrors[*err] = struct{}{}
 | 
			
		||||
	d.savedStrictErrors = append(d.savedStrictErrors, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *decodeState) appendStrictFieldStackKey(key string) {
 | 
			
		||||
	if !d.disallowDuplicateFields && !d.disallowUnknownFields {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if len(d.strictFieldStack) > 0 {
 | 
			
		||||
		d.strictFieldStack = append(d.strictFieldStack, ".", key)
 | 
			
		||||
	} else {
 | 
			
		||||
		d.strictFieldStack = append(d.strictFieldStack, key)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *decodeState) appendStrictFieldStackIndex(i int) {
 | 
			
		||||
	if !d.disallowDuplicateFields && !d.disallowUnknownFields {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	d.strictFieldStack = append(d.strictFieldStack, "[", strconv.Itoa(i), "]")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type strictErrType string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	unknownStrictErrType   strictErrType = "unknown field"
 | 
			
		||||
	duplicateStrictErrType strictErrType = "duplicate field"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// strictError is a strict decoding error
 | 
			
		||||
// It has an ErrType (either unknown or duplicate)
 | 
			
		||||
// and a path to the erroneous field
 | 
			
		||||
type strictError struct {
 | 
			
		||||
	ErrType strictErrType
 | 
			
		||||
	Path    string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *strictError) Error() string {
 | 
			
		||||
	return string(e.ErrType) + " " + strconv.Quote(e.Path)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *strictError) FieldPath() string {
 | 
			
		||||
	return e.Path
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *strictError) SetFieldPath(path string) {
 | 
			
		||||
	e.Path = path
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalStrictError holds errors resulting from use of strict disallow___ decoder directives.
 | 
			
		||||
// If this is returned from Unmarshal(), it means the decoding was successful in all other respects.
 | 
			
		||||
type UnmarshalStrictError struct {
 | 
			
		||||
	Errors []error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *UnmarshalStrictError) Error() string {
 | 
			
		||||
	var b strings.Builder
 | 
			
		||||
	b.WriteString("json: ")
 | 
			
		||||
	for i, err := range e.Errors {
 | 
			
		||||
		if i > 0 {
 | 
			
		||||
			b.WriteString(", ")
 | 
			
		||||
		}
 | 
			
		||||
		b.WriteString(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	return b.String()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										608
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										608
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,608 @@
 | 
			
		||||
// Copyright 2010 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
 | 
			
		||||
 | 
			
		||||
// JSON value parser state machine.
 | 
			
		||||
// Just about at the limit of what is reasonable to write by hand.
 | 
			
		||||
// Some parts are a bit tedious, but overall it nicely factors out the
 | 
			
		||||
// otherwise common code from the multiple scanning functions
 | 
			
		||||
// in this package (Compact, Indent, checkValid, etc).
 | 
			
		||||
//
 | 
			
		||||
// This file starts with two simple examples using the scanner
 | 
			
		||||
// before diving into the scanner itself.
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Valid reports whether data is a valid JSON encoding.
 | 
			
		||||
func Valid(data []byte) bool {
 | 
			
		||||
	scan := newScanner()
 | 
			
		||||
	defer freeScanner(scan)
 | 
			
		||||
	return checkValid(data, scan) == nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkValid verifies that data is valid JSON-encoded data.
 | 
			
		||||
// scan is passed in for use by checkValid to avoid an allocation.
 | 
			
		||||
func checkValid(data []byte, scan *scanner) error {
 | 
			
		||||
	scan.reset()
 | 
			
		||||
	for _, c := range data {
 | 
			
		||||
		scan.bytes++
 | 
			
		||||
		if scan.step(scan, c) == scanError {
 | 
			
		||||
			return scan.err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if scan.eof() == scanError {
 | 
			
		||||
		return scan.err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A SyntaxError is a description of a JSON syntax error.
 | 
			
		||||
type SyntaxError struct {
 | 
			
		||||
	msg    string // description of error
 | 
			
		||||
	Offset int64  // error occurred after reading Offset bytes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *SyntaxError) Error() string { return e.msg }
 | 
			
		||||
 | 
			
		||||
// A scanner is a JSON scanning state machine.
 | 
			
		||||
// Callers call scan.reset and then pass bytes in one at a time
 | 
			
		||||
// by calling scan.step(&scan, c) for each byte.
 | 
			
		||||
// The return value, referred to as an opcode, tells the
 | 
			
		||||
// caller about significant parsing events like beginning
 | 
			
		||||
// and ending literals, objects, and arrays, so that the
 | 
			
		||||
// caller can follow along if it wishes.
 | 
			
		||||
// The return value scanEnd indicates that a single top-level
 | 
			
		||||
// JSON value has been completed, *before* the byte that
 | 
			
		||||
// just got passed in.  (The indication must be delayed in order
 | 
			
		||||
// to recognize the end of numbers: is 123 a whole value or
 | 
			
		||||
// the beginning of 12345e+6?).
 | 
			
		||||
type scanner struct {
 | 
			
		||||
	// The step is a func to be called to execute the next transition.
 | 
			
		||||
	// Also tried using an integer constant and a single func
 | 
			
		||||
	// with a switch, but using the func directly was 10% faster
 | 
			
		||||
	// on a 64-bit Mac Mini, and it's nicer to read.
 | 
			
		||||
	step func(*scanner, byte) int
 | 
			
		||||
 | 
			
		||||
	// Reached end of top-level value.
 | 
			
		||||
	endTop bool
 | 
			
		||||
 | 
			
		||||
	// Stack of what we're in the middle of - array values, object keys, object values.
 | 
			
		||||
	parseState []int
 | 
			
		||||
 | 
			
		||||
	// Error that happened, if any.
 | 
			
		||||
	err error
 | 
			
		||||
 | 
			
		||||
	// total bytes consumed, updated by decoder.Decode (and deliberately
 | 
			
		||||
	// not set to zero by scan.reset)
 | 
			
		||||
	bytes int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var scannerPool = sync.Pool{
 | 
			
		||||
	New: func() any {
 | 
			
		||||
		return &scanner{}
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newScanner() *scanner {
 | 
			
		||||
	scan := scannerPool.Get().(*scanner)
 | 
			
		||||
	// scan.reset by design doesn't set bytes to zero
 | 
			
		||||
	scan.bytes = 0
 | 
			
		||||
	scan.reset()
 | 
			
		||||
	return scan
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func freeScanner(scan *scanner) {
 | 
			
		||||
	// Avoid hanging on to too much memory in extreme cases.
 | 
			
		||||
	if len(scan.parseState) > 1024 {
 | 
			
		||||
		scan.parseState = nil
 | 
			
		||||
	}
 | 
			
		||||
	scannerPool.Put(scan)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// These values are returned by the state transition functions
 | 
			
		||||
// assigned to scanner.state and the method scanner.eof.
 | 
			
		||||
// They give details about the current state of the scan that
 | 
			
		||||
// callers might be interested to know about.
 | 
			
		||||
// It is okay to ignore the return value of any particular
 | 
			
		||||
// call to scanner.state: if one call returns scanError,
 | 
			
		||||
// every subsequent call will return scanError too.
 | 
			
		||||
const (
 | 
			
		||||
	// Continue.
 | 
			
		||||
	scanContinue     = iota // uninteresting byte
 | 
			
		||||
	scanBeginLiteral        // end implied by next result != scanContinue
 | 
			
		||||
	scanBeginObject         // begin object
 | 
			
		||||
	scanObjectKey           // just finished object key (string)
 | 
			
		||||
	scanObjectValue         // just finished non-last object value
 | 
			
		||||
	scanEndObject           // end object (implies scanObjectValue if possible)
 | 
			
		||||
	scanBeginArray          // begin array
 | 
			
		||||
	scanArrayValue          // just finished array value
 | 
			
		||||
	scanEndArray            // end array (implies scanArrayValue if possible)
 | 
			
		||||
	scanSkipSpace           // space byte; can skip; known to be last "continue" result
 | 
			
		||||
 | 
			
		||||
	// Stop.
 | 
			
		||||
	scanEnd   // top-level value ended *before* this byte; known to be first "stop" result
 | 
			
		||||
	scanError // hit an error, scanner.err.
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// These values are stored in the parseState stack.
 | 
			
		||||
// They give the current state of a composite value
 | 
			
		||||
// being scanned. If the parser is inside a nested value
 | 
			
		||||
// the parseState describes the nested state, outermost at entry 0.
 | 
			
		||||
const (
 | 
			
		||||
	parseObjectKey   = iota // parsing object key (before colon)
 | 
			
		||||
	parseObjectValue        // parsing object value (after colon)
 | 
			
		||||
	parseArrayValue         // parsing array value
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// This limits the max nesting depth to prevent stack overflow.
 | 
			
		||||
// This is permitted by https://tools.ietf.org/html/rfc7159#section-9
 | 
			
		||||
const maxNestingDepth = 10000
 | 
			
		||||
 | 
			
		||||
// reset prepares the scanner for use.
 | 
			
		||||
// It must be called before calling s.step.
 | 
			
		||||
func (s *scanner) reset() {
 | 
			
		||||
	s.step = stateBeginValue
 | 
			
		||||
	s.parseState = s.parseState[0:0]
 | 
			
		||||
	s.err = nil
 | 
			
		||||
	s.endTop = false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// eof tells the scanner that the end of input has been reached.
 | 
			
		||||
// It returns a scan status just as s.step does.
 | 
			
		||||
func (s *scanner) eof() int {
 | 
			
		||||
	if s.err != nil {
 | 
			
		||||
		return scanError
 | 
			
		||||
	}
 | 
			
		||||
	if s.endTop {
 | 
			
		||||
		return scanEnd
 | 
			
		||||
	}
 | 
			
		||||
	s.step(s, ' ')
 | 
			
		||||
	if s.endTop {
 | 
			
		||||
		return scanEnd
 | 
			
		||||
	}
 | 
			
		||||
	if s.err == nil {
 | 
			
		||||
		s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
 | 
			
		||||
	}
 | 
			
		||||
	return scanError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// pushParseState pushes a new parse state p onto the parse stack.
 | 
			
		||||
// an error state is returned if maxNestingDepth was exceeded, otherwise successState is returned.
 | 
			
		||||
func (s *scanner) pushParseState(c byte, newParseState int, successState int) int {
 | 
			
		||||
	s.parseState = append(s.parseState, newParseState)
 | 
			
		||||
	if len(s.parseState) <= maxNestingDepth {
 | 
			
		||||
		return successState
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "exceeded max depth")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// popParseState pops a parse state (already obtained) off the stack
 | 
			
		||||
// and updates s.step accordingly.
 | 
			
		||||
func (s *scanner) popParseState() {
 | 
			
		||||
	n := len(s.parseState) - 1
 | 
			
		||||
	s.parseState = s.parseState[0:n]
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		s.step = stateEndTop
 | 
			
		||||
		s.endTop = true
 | 
			
		||||
	} else {
 | 
			
		||||
		s.step = stateEndValue
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isSpace(c byte) bool {
 | 
			
		||||
	return c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateBeginValueOrEmpty is the state after reading `[`.
 | 
			
		||||
func stateBeginValueOrEmpty(s *scanner, c byte) int {
 | 
			
		||||
	if isSpace(c) {
 | 
			
		||||
		return scanSkipSpace
 | 
			
		||||
	}
 | 
			
		||||
	if c == ']' {
 | 
			
		||||
		return stateEndValue(s, c)
 | 
			
		||||
	}
 | 
			
		||||
	return stateBeginValue(s, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateBeginValue is the state at the beginning of the input.
 | 
			
		||||
func stateBeginValue(s *scanner, c byte) int {
 | 
			
		||||
	if isSpace(c) {
 | 
			
		||||
		return scanSkipSpace
 | 
			
		||||
	}
 | 
			
		||||
	switch c {
 | 
			
		||||
	case '{':
 | 
			
		||||
		s.step = stateBeginStringOrEmpty
 | 
			
		||||
		return s.pushParseState(c, parseObjectKey, scanBeginObject)
 | 
			
		||||
	case '[':
 | 
			
		||||
		s.step = stateBeginValueOrEmpty
 | 
			
		||||
		return s.pushParseState(c, parseArrayValue, scanBeginArray)
 | 
			
		||||
	case '"':
 | 
			
		||||
		s.step = stateInString
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	case '-':
 | 
			
		||||
		s.step = stateNeg
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	case '0': // beginning of 0.123
 | 
			
		||||
		s.step = state0
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	case 't': // beginning of true
 | 
			
		||||
		s.step = stateT
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	case 'f': // beginning of false
 | 
			
		||||
		s.step = stateF
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	case 'n': // beginning of null
 | 
			
		||||
		s.step = stateN
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	}
 | 
			
		||||
	if '1' <= c && c <= '9' { // beginning of 1234.5
 | 
			
		||||
		s.step = state1
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "looking for beginning of value")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateBeginStringOrEmpty is the state after reading `{`.
 | 
			
		||||
func stateBeginStringOrEmpty(s *scanner, c byte) int {
 | 
			
		||||
	if isSpace(c) {
 | 
			
		||||
		return scanSkipSpace
 | 
			
		||||
	}
 | 
			
		||||
	if c == '}' {
 | 
			
		||||
		n := len(s.parseState)
 | 
			
		||||
		s.parseState[n-1] = parseObjectValue
 | 
			
		||||
		return stateEndValue(s, c)
 | 
			
		||||
	}
 | 
			
		||||
	return stateBeginString(s, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateBeginString is the state after reading `{"key": value,`.
 | 
			
		||||
func stateBeginString(s *scanner, c byte) int {
 | 
			
		||||
	if isSpace(c) {
 | 
			
		||||
		return scanSkipSpace
 | 
			
		||||
	}
 | 
			
		||||
	if c == '"' {
 | 
			
		||||
		s.step = stateInString
 | 
			
		||||
		return scanBeginLiteral
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "looking for beginning of object key string")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateEndValue is the state after completing a value,
 | 
			
		||||
// such as after reading `{}` or `true` or `["x"`.
 | 
			
		||||
func stateEndValue(s *scanner, c byte) int {
 | 
			
		||||
	n := len(s.parseState)
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		// Completed top-level before the current byte.
 | 
			
		||||
		s.step = stateEndTop
 | 
			
		||||
		s.endTop = true
 | 
			
		||||
		return stateEndTop(s, c)
 | 
			
		||||
	}
 | 
			
		||||
	if isSpace(c) {
 | 
			
		||||
		s.step = stateEndValue
 | 
			
		||||
		return scanSkipSpace
 | 
			
		||||
	}
 | 
			
		||||
	ps := s.parseState[n-1]
 | 
			
		||||
	switch ps {
 | 
			
		||||
	case parseObjectKey:
 | 
			
		||||
		if c == ':' {
 | 
			
		||||
			s.parseState[n-1] = parseObjectValue
 | 
			
		||||
			s.step = stateBeginValue
 | 
			
		||||
			return scanObjectKey
 | 
			
		||||
		}
 | 
			
		||||
		return s.error(c, "after object key")
 | 
			
		||||
	case parseObjectValue:
 | 
			
		||||
		if c == ',' {
 | 
			
		||||
			s.parseState[n-1] = parseObjectKey
 | 
			
		||||
			s.step = stateBeginString
 | 
			
		||||
			return scanObjectValue
 | 
			
		||||
		}
 | 
			
		||||
		if c == '}' {
 | 
			
		||||
			s.popParseState()
 | 
			
		||||
			return scanEndObject
 | 
			
		||||
		}
 | 
			
		||||
		return s.error(c, "after object key:value pair")
 | 
			
		||||
	case parseArrayValue:
 | 
			
		||||
		if c == ',' {
 | 
			
		||||
			s.step = stateBeginValue
 | 
			
		||||
			return scanArrayValue
 | 
			
		||||
		}
 | 
			
		||||
		if c == ']' {
 | 
			
		||||
			s.popParseState()
 | 
			
		||||
			return scanEndArray
 | 
			
		||||
		}
 | 
			
		||||
		return s.error(c, "after array element")
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateEndTop is the state after finishing the top-level value,
 | 
			
		||||
// such as after reading `{}` or `[1,2,3]`.
 | 
			
		||||
// Only space characters should be seen now.
 | 
			
		||||
func stateEndTop(s *scanner, c byte) int {
 | 
			
		||||
	if !isSpace(c) {
 | 
			
		||||
		// Complain about non-space byte on next call.
 | 
			
		||||
		s.error(c, "after top-level value")
 | 
			
		||||
	}
 | 
			
		||||
	return scanEnd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateInString is the state after reading `"`.
 | 
			
		||||
func stateInString(s *scanner, c byte) int {
 | 
			
		||||
	if c == '"' {
 | 
			
		||||
		s.step = stateEndValue
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	if c == '\\' {
 | 
			
		||||
		s.step = stateInStringEsc
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	if c < 0x20 {
 | 
			
		||||
		return s.error(c, "in string literal")
 | 
			
		||||
	}
 | 
			
		||||
	return scanContinue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateInStringEsc is the state after reading `"\` during a quoted string.
 | 
			
		||||
func stateInStringEsc(s *scanner, c byte) int {
 | 
			
		||||
	switch c {
 | 
			
		||||
	case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
 | 
			
		||||
		s.step = stateInString
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	case 'u':
 | 
			
		||||
		s.step = stateInStringEscU
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in string escape code")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateInStringEscU is the state after reading `"\u` during a quoted string.
 | 
			
		||||
func stateInStringEscU(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
			
		||||
		s.step = stateInStringEscU1
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	// numbers
 | 
			
		||||
	return s.error(c, "in \\u hexadecimal character escape")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
 | 
			
		||||
func stateInStringEscU1(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
			
		||||
		s.step = stateInStringEscU12
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	// numbers
 | 
			
		||||
	return s.error(c, "in \\u hexadecimal character escape")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
 | 
			
		||||
func stateInStringEscU12(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
			
		||||
		s.step = stateInStringEscU123
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	// numbers
 | 
			
		||||
	return s.error(c, "in \\u hexadecimal character escape")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
 | 
			
		||||
func stateInStringEscU123(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
			
		||||
		s.step = stateInString
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	// numbers
 | 
			
		||||
	return s.error(c, "in \\u hexadecimal character escape")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateNeg is the state after reading `-` during a number.
 | 
			
		||||
func stateNeg(s *scanner, c byte) int {
 | 
			
		||||
	if c == '0' {
 | 
			
		||||
		s.step = state0
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	if '1' <= c && c <= '9' {
 | 
			
		||||
		s.step = state1
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in numeric literal")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// state1 is the state after reading a non-zero integer during a number,
 | 
			
		||||
// such as after reading `1` or `100` but not `0`.
 | 
			
		||||
func state1(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' {
 | 
			
		||||
		s.step = state1
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return state0(s, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// state0 is the state after reading `0` during a number.
 | 
			
		||||
func state0(s *scanner, c byte) int {
 | 
			
		||||
	if c == '.' {
 | 
			
		||||
		s.step = stateDot
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	if c == 'e' || c == 'E' {
 | 
			
		||||
		s.step = stateE
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return stateEndValue(s, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateDot is the state after reading the integer and decimal point in a number,
 | 
			
		||||
// such as after reading `1.`.
 | 
			
		||||
func stateDot(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' {
 | 
			
		||||
		s.step = stateDot0
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "after decimal point in numeric literal")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateDot0 is the state after reading the integer, decimal point, and subsequent
 | 
			
		||||
// digits of a number, such as after reading `3.14`.
 | 
			
		||||
func stateDot0(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' {
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	if c == 'e' || c == 'E' {
 | 
			
		||||
		s.step = stateE
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return stateEndValue(s, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateE is the state after reading the mantissa and e in a number,
 | 
			
		||||
// such as after reading `314e` or `0.314e`.
 | 
			
		||||
func stateE(s *scanner, c byte) int {
 | 
			
		||||
	if c == '+' || c == '-' {
 | 
			
		||||
		s.step = stateESign
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return stateESign(s, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateESign is the state after reading the mantissa, e, and sign in a number,
 | 
			
		||||
// such as after reading `314e-` or `0.314e+`.
 | 
			
		||||
func stateESign(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' {
 | 
			
		||||
		s.step = stateE0
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in exponent of numeric literal")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateE0 is the state after reading the mantissa, e, optional sign,
 | 
			
		||||
// and at least one digit of the exponent in a number,
 | 
			
		||||
// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
 | 
			
		||||
func stateE0(s *scanner, c byte) int {
 | 
			
		||||
	if '0' <= c && c <= '9' {
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return stateEndValue(s, c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateT is the state after reading `t`.
 | 
			
		||||
func stateT(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'r' {
 | 
			
		||||
		s.step = stateTr
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal true (expecting 'r')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateTr is the state after reading `tr`.
 | 
			
		||||
func stateTr(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'u' {
 | 
			
		||||
		s.step = stateTru
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal true (expecting 'u')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateTru is the state after reading `tru`.
 | 
			
		||||
func stateTru(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'e' {
 | 
			
		||||
		s.step = stateEndValue
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal true (expecting 'e')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateF is the state after reading `f`.
 | 
			
		||||
func stateF(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'a' {
 | 
			
		||||
		s.step = stateFa
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal false (expecting 'a')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateFa is the state after reading `fa`.
 | 
			
		||||
func stateFa(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'l' {
 | 
			
		||||
		s.step = stateFal
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal false (expecting 'l')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateFal is the state after reading `fal`.
 | 
			
		||||
func stateFal(s *scanner, c byte) int {
 | 
			
		||||
	if c == 's' {
 | 
			
		||||
		s.step = stateFals
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal false (expecting 's')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateFals is the state after reading `fals`.
 | 
			
		||||
func stateFals(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'e' {
 | 
			
		||||
		s.step = stateEndValue
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal false (expecting 'e')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateN is the state after reading `n`.
 | 
			
		||||
func stateN(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'u' {
 | 
			
		||||
		s.step = stateNu
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal null (expecting 'u')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateNu is the state after reading `nu`.
 | 
			
		||||
func stateNu(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'l' {
 | 
			
		||||
		s.step = stateNul
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal null (expecting 'l')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateNul is the state after reading `nul`.
 | 
			
		||||
func stateNul(s *scanner, c byte) int {
 | 
			
		||||
	if c == 'l' {
 | 
			
		||||
		s.step = stateEndValue
 | 
			
		||||
		return scanContinue
 | 
			
		||||
	}
 | 
			
		||||
	return s.error(c, "in literal null (expecting 'l')")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stateError is the state after reaching a syntax error,
 | 
			
		||||
// such as after reading `[1}` or `5.1.2`.
 | 
			
		||||
func stateError(s *scanner, c byte) int {
 | 
			
		||||
	return scanError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// error records an error and switches to the error state.
 | 
			
		||||
func (s *scanner) error(c byte, context string) int {
 | 
			
		||||
	s.step = stateError
 | 
			
		||||
	s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
 | 
			
		||||
	return scanError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// quoteChar formats c as a quoted character literal
 | 
			
		||||
func quoteChar(c byte) string {
 | 
			
		||||
	// special cases - different from quoted strings
 | 
			
		||||
	if c == '\'' {
 | 
			
		||||
		return `'\''`
 | 
			
		||||
	}
 | 
			
		||||
	if c == '"' {
 | 
			
		||||
		return `'"'`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// use quoted string with different quotation marks
 | 
			
		||||
	s := strconv.Quote(string(c))
 | 
			
		||||
	return "'" + s[1:len(s)-1] + "'"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										519
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										519
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,519 @@
 | 
			
		||||
// Copyright 2010 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 (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A Decoder reads and decodes JSON values from an input stream.
 | 
			
		||||
type Decoder struct {
 | 
			
		||||
	r       io.Reader
 | 
			
		||||
	buf     []byte
 | 
			
		||||
	d       decodeState
 | 
			
		||||
	scanp   int   // start of unread data in buf
 | 
			
		||||
	scanned int64 // amount of data already scanned
 | 
			
		||||
	scan    scanner
 | 
			
		||||
	err     error
 | 
			
		||||
 | 
			
		||||
	tokenState int
 | 
			
		||||
	tokenStack []int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewDecoder returns a new decoder that reads from r.
 | 
			
		||||
//
 | 
			
		||||
// The decoder introduces its own buffering and may
 | 
			
		||||
// read data from r beyond the JSON values requested.
 | 
			
		||||
func NewDecoder(r io.Reader) *Decoder {
 | 
			
		||||
	return &Decoder{r: r}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
 | 
			
		||||
// Number instead of as a float64.
 | 
			
		||||
func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
 | 
			
		||||
 | 
			
		||||
// DisallowUnknownFields causes the Decoder to return an error when the destination
 | 
			
		||||
// is a struct and the input contains object keys which do not match any
 | 
			
		||||
// non-ignored, exported fields in the destination.
 | 
			
		||||
func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true }
 | 
			
		||||
 | 
			
		||||
// Decode reads the next JSON-encoded value from its
 | 
			
		||||
// input and stores it in the value pointed to by v.
 | 
			
		||||
//
 | 
			
		||||
// See the documentation for Unmarshal for details about
 | 
			
		||||
// the conversion of JSON into a Go value.
 | 
			
		||||
func (dec *Decoder) Decode(v any) error {
 | 
			
		||||
	if dec.err != nil {
 | 
			
		||||
		return dec.err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := dec.tokenPrepareForDecode(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !dec.tokenValueAllowed() {
 | 
			
		||||
		return &SyntaxError{msg: "not at beginning of value", Offset: dec.InputOffset()}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Read whole value into buffer.
 | 
			
		||||
	n, err := dec.readValue()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
 | 
			
		||||
	dec.scanp += n
 | 
			
		||||
 | 
			
		||||
	// Don't save err from unmarshal into dec.err:
 | 
			
		||||
	// the connection is still usable since we read a complete JSON
 | 
			
		||||
	// object from it before the error happened.
 | 
			
		||||
	err = dec.d.unmarshal(v)
 | 
			
		||||
 | 
			
		||||
	// fixup token streaming state
 | 
			
		||||
	dec.tokenValueEnd()
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Buffered returns a reader of the data remaining in the Decoder's
 | 
			
		||||
// buffer. The reader is valid until the next call to Decode.
 | 
			
		||||
func (dec *Decoder) Buffered() io.Reader {
 | 
			
		||||
	return bytes.NewReader(dec.buf[dec.scanp:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// readValue reads a JSON value into dec.buf.
 | 
			
		||||
// It returns the length of the encoding.
 | 
			
		||||
func (dec *Decoder) readValue() (int, error) {
 | 
			
		||||
	dec.scan.reset()
 | 
			
		||||
 | 
			
		||||
	scanp := dec.scanp
 | 
			
		||||
	var err error
 | 
			
		||||
Input:
 | 
			
		||||
	// help the compiler see that scanp is never negative, so it can remove
 | 
			
		||||
	// some bounds checks below.
 | 
			
		||||
	for scanp >= 0 {
 | 
			
		||||
 | 
			
		||||
		// Look in the buffer for a new value.
 | 
			
		||||
		for ; scanp < len(dec.buf); scanp++ {
 | 
			
		||||
			c := dec.buf[scanp]
 | 
			
		||||
			dec.scan.bytes++
 | 
			
		||||
			switch dec.scan.step(&dec.scan, c) {
 | 
			
		||||
			case scanEnd:
 | 
			
		||||
				// scanEnd is delayed one byte so we decrement
 | 
			
		||||
				// the scanner bytes count by 1 to ensure that
 | 
			
		||||
				// this value is correct in the next call of Decode.
 | 
			
		||||
				dec.scan.bytes--
 | 
			
		||||
				break Input
 | 
			
		||||
			case scanEndObject, scanEndArray:
 | 
			
		||||
				// scanEnd is delayed one byte.
 | 
			
		||||
				// We might block trying to get that byte from src,
 | 
			
		||||
				// so instead invent a space byte.
 | 
			
		||||
				if stateEndValue(&dec.scan, ' ') == scanEnd {
 | 
			
		||||
					scanp++
 | 
			
		||||
					break Input
 | 
			
		||||
				}
 | 
			
		||||
			case scanError:
 | 
			
		||||
				dec.err = dec.scan.err
 | 
			
		||||
				return 0, dec.scan.err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Did the last read have an error?
 | 
			
		||||
		// Delayed until now to allow buffer scan.
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err == io.EOF {
 | 
			
		||||
				if dec.scan.step(&dec.scan, ' ') == scanEnd {
 | 
			
		||||
					break Input
 | 
			
		||||
				}
 | 
			
		||||
				if nonSpace(dec.buf) {
 | 
			
		||||
					err = io.ErrUnexpectedEOF
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			dec.err = err
 | 
			
		||||
			return 0, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		n := scanp - dec.scanp
 | 
			
		||||
		err = dec.refill()
 | 
			
		||||
		scanp = dec.scanp + n
 | 
			
		||||
	}
 | 
			
		||||
	return scanp - dec.scanp, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dec *Decoder) refill() error {
 | 
			
		||||
	// Make room to read more into the buffer.
 | 
			
		||||
	// First slide down data already consumed.
 | 
			
		||||
	if dec.scanp > 0 {
 | 
			
		||||
		dec.scanned += int64(dec.scanp)
 | 
			
		||||
		n := copy(dec.buf, dec.buf[dec.scanp:])
 | 
			
		||||
		dec.buf = dec.buf[:n]
 | 
			
		||||
		dec.scanp = 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Grow buffer if not large enough.
 | 
			
		||||
	const minRead = 512
 | 
			
		||||
	if cap(dec.buf)-len(dec.buf) < minRead {
 | 
			
		||||
		newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
 | 
			
		||||
		copy(newBuf, dec.buf)
 | 
			
		||||
		dec.buf = newBuf
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Read. Delay error for next iteration (after scan).
 | 
			
		||||
	n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
 | 
			
		||||
	dec.buf = dec.buf[0 : len(dec.buf)+n]
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func nonSpace(b []byte) bool {
 | 
			
		||||
	for _, c := range b {
 | 
			
		||||
		if !isSpace(c) {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An Encoder writes JSON values to an output stream.
 | 
			
		||||
type Encoder struct {
 | 
			
		||||
	w          io.Writer
 | 
			
		||||
	err        error
 | 
			
		||||
	escapeHTML bool
 | 
			
		||||
 | 
			
		||||
	indentBuf    *bytes.Buffer
 | 
			
		||||
	indentPrefix string
 | 
			
		||||
	indentValue  string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewEncoder returns a new encoder that writes to w.
 | 
			
		||||
func NewEncoder(w io.Writer) *Encoder {
 | 
			
		||||
	return &Encoder{w: w, escapeHTML: true}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Encode writes the JSON encoding of v to the stream,
 | 
			
		||||
// followed by a newline character.
 | 
			
		||||
//
 | 
			
		||||
// See the documentation for Marshal for details about the
 | 
			
		||||
// conversion of Go values to JSON.
 | 
			
		||||
func (enc *Encoder) Encode(v any) error {
 | 
			
		||||
	if enc.err != nil {
 | 
			
		||||
		return enc.err
 | 
			
		||||
	}
 | 
			
		||||
	e := newEncodeState()
 | 
			
		||||
	err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Terminate each value with a newline.
 | 
			
		||||
	// This makes the output look a little nicer
 | 
			
		||||
	// when debugging, and some kind of space
 | 
			
		||||
	// is required if the encoded value was a number,
 | 
			
		||||
	// so that the reader knows there aren't more
 | 
			
		||||
	// digits coming.
 | 
			
		||||
	e.WriteByte('\n')
 | 
			
		||||
 | 
			
		||||
	b := e.Bytes()
 | 
			
		||||
	if enc.indentPrefix != "" || enc.indentValue != "" {
 | 
			
		||||
		if enc.indentBuf == nil {
 | 
			
		||||
			enc.indentBuf = new(bytes.Buffer)
 | 
			
		||||
		}
 | 
			
		||||
		enc.indentBuf.Reset()
 | 
			
		||||
		err = Indent(enc.indentBuf, b, enc.indentPrefix, enc.indentValue)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		b = enc.indentBuf.Bytes()
 | 
			
		||||
	}
 | 
			
		||||
	if _, err = enc.w.Write(b); err != nil {
 | 
			
		||||
		enc.err = err
 | 
			
		||||
	}
 | 
			
		||||
	encodeStatePool.Put(e)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetIndent instructs the encoder to format each subsequent encoded
 | 
			
		||||
// value as if indented by the package-level function Indent(dst, src, prefix, indent).
 | 
			
		||||
// Calling SetIndent("", "") disables indentation.
 | 
			
		||||
func (enc *Encoder) SetIndent(prefix, indent string) {
 | 
			
		||||
	enc.indentPrefix = prefix
 | 
			
		||||
	enc.indentValue = indent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetEscapeHTML specifies whether problematic HTML characters
 | 
			
		||||
// should be escaped inside JSON quoted strings.
 | 
			
		||||
// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e
 | 
			
		||||
// to avoid certain safety problems that can arise when embedding JSON in HTML.
 | 
			
		||||
//
 | 
			
		||||
// In non-HTML settings where the escaping interferes with the readability
 | 
			
		||||
// of the output, SetEscapeHTML(false) disables this behavior.
 | 
			
		||||
func (enc *Encoder) SetEscapeHTML(on bool) {
 | 
			
		||||
	enc.escapeHTML = on
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
// RawMessage is a raw encoded JSON value.
 | 
			
		||||
// It implements Marshaler and Unmarshaler and can
 | 
			
		||||
// be used to delay JSON decoding or precompute a JSON encoding.
 | 
			
		||||
type RawMessage []byte
 | 
			
		||||
 | 
			
		||||
// MarshalJSON returns m as the JSON encoding of m.
 | 
			
		||||
func (m RawMessage) MarshalJSON() ([]byte, error) {
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		return []byte("null"), nil
 | 
			
		||||
	}
 | 
			
		||||
	return m, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalJSON sets *m to a copy of data.
 | 
			
		||||
func (m *RawMessage) UnmarshalJSON(data []byte) error {
 | 
			
		||||
	if m == nil {
 | 
			
		||||
		return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
 | 
			
		||||
	}
 | 
			
		||||
	*m = append((*m)[0:0], data...)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
var _ Marshaler = (*RawMessage)(nil)
 | 
			
		||||
var _ Unmarshaler = (*RawMessage)(nil)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
// A Token holds a value of one of these types:
 | 
			
		||||
//
 | 
			
		||||
//	Delim, for the four JSON delimiters [ ] { }
 | 
			
		||||
//	bool, for JSON booleans
 | 
			
		||||
//	float64, for JSON numbers
 | 
			
		||||
//	Number, for JSON numbers
 | 
			
		||||
//	string, for JSON string literals
 | 
			
		||||
//	nil, for JSON null
 | 
			
		||||
//
 | 
			
		||||
type Token any
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	tokenTopValue = iota
 | 
			
		||||
	tokenArrayStart
 | 
			
		||||
	tokenArrayValue
 | 
			
		||||
	tokenArrayComma
 | 
			
		||||
	tokenObjectStart
 | 
			
		||||
	tokenObjectKey
 | 
			
		||||
	tokenObjectColon
 | 
			
		||||
	tokenObjectValue
 | 
			
		||||
	tokenObjectComma
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// advance tokenstate from a separator state to a value state
 | 
			
		||||
func (dec *Decoder) tokenPrepareForDecode() error {
 | 
			
		||||
	// Note: Not calling peek before switch, to avoid
 | 
			
		||||
	// putting peek into the standard Decode path.
 | 
			
		||||
	// peek is only called when using the Token API.
 | 
			
		||||
	switch dec.tokenState {
 | 
			
		||||
	case tokenArrayComma:
 | 
			
		||||
		c, err := dec.peek()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if c != ',' {
 | 
			
		||||
			return &SyntaxError{"expected comma after array element", dec.InputOffset()}
 | 
			
		||||
		}
 | 
			
		||||
		dec.scanp++
 | 
			
		||||
		dec.tokenState = tokenArrayValue
 | 
			
		||||
	case tokenObjectColon:
 | 
			
		||||
		c, err := dec.peek()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if c != ':' {
 | 
			
		||||
			return &SyntaxError{"expected colon after object key", dec.InputOffset()}
 | 
			
		||||
		}
 | 
			
		||||
		dec.scanp++
 | 
			
		||||
		dec.tokenState = tokenObjectValue
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dec *Decoder) tokenValueAllowed() bool {
 | 
			
		||||
	switch dec.tokenState {
 | 
			
		||||
	case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dec *Decoder) tokenValueEnd() {
 | 
			
		||||
	switch dec.tokenState {
 | 
			
		||||
	case tokenArrayStart, tokenArrayValue:
 | 
			
		||||
		dec.tokenState = tokenArrayComma
 | 
			
		||||
	case tokenObjectValue:
 | 
			
		||||
		dec.tokenState = tokenObjectComma
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
// A Delim is a JSON array or object delimiter, one of [ ] { or }.
 | 
			
		||||
type Delim rune
 | 
			
		||||
 | 
			
		||||
func (d Delim) String() string {
 | 
			
		||||
	return string(d)
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Token returns the next JSON token in the input stream.
 | 
			
		||||
// At the end of the input stream, Token returns nil, io.EOF.
 | 
			
		||||
//
 | 
			
		||||
// Token guarantees that the delimiters [ ] { } it returns are
 | 
			
		||||
// properly nested and matched: if Token encounters an unexpected
 | 
			
		||||
// delimiter in the input, it will return an error.
 | 
			
		||||
//
 | 
			
		||||
// The input stream consists of basic JSON values—bool, string,
 | 
			
		||||
// number, and null—along with delimiters [ ] { } of type Delim
 | 
			
		||||
// to mark the start and end of arrays and objects.
 | 
			
		||||
// Commas and colons are elided.
 | 
			
		||||
func (dec *Decoder) Token() (Token, error) {
 | 
			
		||||
	for {
 | 
			
		||||
		c, err := dec.peek()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		switch c {
 | 
			
		||||
		case '[':
 | 
			
		||||
			if !dec.tokenValueAllowed() {
 | 
			
		||||
				return dec.tokenError(c)
 | 
			
		||||
			}
 | 
			
		||||
			dec.scanp++
 | 
			
		||||
			dec.tokenStack = append(dec.tokenStack, dec.tokenState)
 | 
			
		||||
			dec.tokenState = tokenArrayStart
 | 
			
		||||
			return Delim('['), nil
 | 
			
		||||
 | 
			
		||||
		case ']':
 | 
			
		||||
			if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
 | 
			
		||||
				return dec.tokenError(c)
 | 
			
		||||
			}
 | 
			
		||||
			dec.scanp++
 | 
			
		||||
			dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
 | 
			
		||||
			dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
 | 
			
		||||
			dec.tokenValueEnd()
 | 
			
		||||
			return Delim(']'), nil
 | 
			
		||||
 | 
			
		||||
		case '{':
 | 
			
		||||
			if !dec.tokenValueAllowed() {
 | 
			
		||||
				return dec.tokenError(c)
 | 
			
		||||
			}
 | 
			
		||||
			dec.scanp++
 | 
			
		||||
			dec.tokenStack = append(dec.tokenStack, dec.tokenState)
 | 
			
		||||
			dec.tokenState = tokenObjectStart
 | 
			
		||||
			return Delim('{'), nil
 | 
			
		||||
 | 
			
		||||
		case '}':
 | 
			
		||||
			if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
 | 
			
		||||
				return dec.tokenError(c)
 | 
			
		||||
			}
 | 
			
		||||
			dec.scanp++
 | 
			
		||||
			dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
 | 
			
		||||
			dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
 | 
			
		||||
			dec.tokenValueEnd()
 | 
			
		||||
			return Delim('}'), nil
 | 
			
		||||
 | 
			
		||||
		case ':':
 | 
			
		||||
			if dec.tokenState != tokenObjectColon {
 | 
			
		||||
				return dec.tokenError(c)
 | 
			
		||||
			}
 | 
			
		||||
			dec.scanp++
 | 
			
		||||
			dec.tokenState = tokenObjectValue
 | 
			
		||||
			continue
 | 
			
		||||
 | 
			
		||||
		case ',':
 | 
			
		||||
			if dec.tokenState == tokenArrayComma {
 | 
			
		||||
				dec.scanp++
 | 
			
		||||
				dec.tokenState = tokenArrayValue
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if dec.tokenState == tokenObjectComma {
 | 
			
		||||
				dec.scanp++
 | 
			
		||||
				dec.tokenState = tokenObjectKey
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			return dec.tokenError(c)
 | 
			
		||||
 | 
			
		||||
		case '"':
 | 
			
		||||
			if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
 | 
			
		||||
				var x string
 | 
			
		||||
				old := dec.tokenState
 | 
			
		||||
				dec.tokenState = tokenTopValue
 | 
			
		||||
				err := dec.Decode(&x)
 | 
			
		||||
				dec.tokenState = old
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return nil, err
 | 
			
		||||
				}
 | 
			
		||||
				dec.tokenState = tokenObjectColon
 | 
			
		||||
				return x, nil
 | 
			
		||||
			}
 | 
			
		||||
			fallthrough
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			if !dec.tokenValueAllowed() {
 | 
			
		||||
				return dec.tokenError(c)
 | 
			
		||||
			}
 | 
			
		||||
			var x any
 | 
			
		||||
			if err := dec.Decode(&x); err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			return x, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dec *Decoder) tokenError(c byte) (Token, error) {
 | 
			
		||||
	var context string
 | 
			
		||||
	switch dec.tokenState {
 | 
			
		||||
	case tokenTopValue:
 | 
			
		||||
		context = " looking for beginning of value"
 | 
			
		||||
	case tokenArrayStart, tokenArrayValue, tokenObjectValue:
 | 
			
		||||
		context = " looking for beginning of value"
 | 
			
		||||
	case tokenArrayComma:
 | 
			
		||||
		context = " after array element"
 | 
			
		||||
	case tokenObjectKey:
 | 
			
		||||
		context = " looking for beginning of object key string"
 | 
			
		||||
	case tokenObjectColon:
 | 
			
		||||
		context = " after object key"
 | 
			
		||||
	case tokenObjectComma:
 | 
			
		||||
		context = " after object key:value pair"
 | 
			
		||||
	}
 | 
			
		||||
	return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.InputOffset()}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// More reports whether there is another element in the
 | 
			
		||||
// current array or object being parsed.
 | 
			
		||||
func (dec *Decoder) More() bool {
 | 
			
		||||
	c, err := dec.peek()
 | 
			
		||||
	return err == nil && c != ']' && c != '}'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dec *Decoder) peek() (byte, error) {
 | 
			
		||||
	var err error
 | 
			
		||||
	for {
 | 
			
		||||
		for i := dec.scanp; i < len(dec.buf); i++ {
 | 
			
		||||
			c := dec.buf[i]
 | 
			
		||||
			if isSpace(c) {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			dec.scanp = i
 | 
			
		||||
			return c, nil
 | 
			
		||||
		}
 | 
			
		||||
		// buffer has been scanned, now report any error
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return 0, err
 | 
			
		||||
		}
 | 
			
		||||
		err = dec.refill()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InputOffset returns the input stream byte offset of the current decoder position.
 | 
			
		||||
// The offset gives the location of the end of the most recently returned token
 | 
			
		||||
// and the beginning of the next token.
 | 
			
		||||
func (dec *Decoder) InputOffset() int64 {
 | 
			
		||||
	return dec.scanned + int64(dec.scanp)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										218
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/tables.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/tables.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
			
		||||
// Copyright 2016 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 "unicode/utf8"
 | 
			
		||||
 | 
			
		||||
// safeSet holds the value true if the ASCII character with the given array
 | 
			
		||||
// position can be represented inside a JSON string without any further
 | 
			
		||||
// escaping.
 | 
			
		||||
//
 | 
			
		||||
// All values are true except for the ASCII control characters (0-31), the
 | 
			
		||||
// double quote ("), and the backslash character ("\").
 | 
			
		||||
var safeSet = [utf8.RuneSelf]bool{
 | 
			
		||||
	' ':      true,
 | 
			
		||||
	'!':      true,
 | 
			
		||||
	'"':      false,
 | 
			
		||||
	'#':      true,
 | 
			
		||||
	'$':      true,
 | 
			
		||||
	'%':      true,
 | 
			
		||||
	'&':      true,
 | 
			
		||||
	'\'':     true,
 | 
			
		||||
	'(':      true,
 | 
			
		||||
	')':      true,
 | 
			
		||||
	'*':      true,
 | 
			
		||||
	'+':      true,
 | 
			
		||||
	',':      true,
 | 
			
		||||
	'-':      true,
 | 
			
		||||
	'.':      true,
 | 
			
		||||
	'/':      true,
 | 
			
		||||
	'0':      true,
 | 
			
		||||
	'1':      true,
 | 
			
		||||
	'2':      true,
 | 
			
		||||
	'3':      true,
 | 
			
		||||
	'4':      true,
 | 
			
		||||
	'5':      true,
 | 
			
		||||
	'6':      true,
 | 
			
		||||
	'7':      true,
 | 
			
		||||
	'8':      true,
 | 
			
		||||
	'9':      true,
 | 
			
		||||
	':':      true,
 | 
			
		||||
	';':      true,
 | 
			
		||||
	'<':      true,
 | 
			
		||||
	'=':      true,
 | 
			
		||||
	'>':      true,
 | 
			
		||||
	'?':      true,
 | 
			
		||||
	'@':      true,
 | 
			
		||||
	'A':      true,
 | 
			
		||||
	'B':      true,
 | 
			
		||||
	'C':      true,
 | 
			
		||||
	'D':      true,
 | 
			
		||||
	'E':      true,
 | 
			
		||||
	'F':      true,
 | 
			
		||||
	'G':      true,
 | 
			
		||||
	'H':      true,
 | 
			
		||||
	'I':      true,
 | 
			
		||||
	'J':      true,
 | 
			
		||||
	'K':      true,
 | 
			
		||||
	'L':      true,
 | 
			
		||||
	'M':      true,
 | 
			
		||||
	'N':      true,
 | 
			
		||||
	'O':      true,
 | 
			
		||||
	'P':      true,
 | 
			
		||||
	'Q':      true,
 | 
			
		||||
	'R':      true,
 | 
			
		||||
	'S':      true,
 | 
			
		||||
	'T':      true,
 | 
			
		||||
	'U':      true,
 | 
			
		||||
	'V':      true,
 | 
			
		||||
	'W':      true,
 | 
			
		||||
	'X':      true,
 | 
			
		||||
	'Y':      true,
 | 
			
		||||
	'Z':      true,
 | 
			
		||||
	'[':      true,
 | 
			
		||||
	'\\':     false,
 | 
			
		||||
	']':      true,
 | 
			
		||||
	'^':      true,
 | 
			
		||||
	'_':      true,
 | 
			
		||||
	'`':      true,
 | 
			
		||||
	'a':      true,
 | 
			
		||||
	'b':      true,
 | 
			
		||||
	'c':      true,
 | 
			
		||||
	'd':      true,
 | 
			
		||||
	'e':      true,
 | 
			
		||||
	'f':      true,
 | 
			
		||||
	'g':      true,
 | 
			
		||||
	'h':      true,
 | 
			
		||||
	'i':      true,
 | 
			
		||||
	'j':      true,
 | 
			
		||||
	'k':      true,
 | 
			
		||||
	'l':      true,
 | 
			
		||||
	'm':      true,
 | 
			
		||||
	'n':      true,
 | 
			
		||||
	'o':      true,
 | 
			
		||||
	'p':      true,
 | 
			
		||||
	'q':      true,
 | 
			
		||||
	'r':      true,
 | 
			
		||||
	's':      true,
 | 
			
		||||
	't':      true,
 | 
			
		||||
	'u':      true,
 | 
			
		||||
	'v':      true,
 | 
			
		||||
	'w':      true,
 | 
			
		||||
	'x':      true,
 | 
			
		||||
	'y':      true,
 | 
			
		||||
	'z':      true,
 | 
			
		||||
	'{':      true,
 | 
			
		||||
	'|':      true,
 | 
			
		||||
	'}':      true,
 | 
			
		||||
	'~':      true,
 | 
			
		||||
	'\u007f': true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// htmlSafeSet holds the value true if the ASCII character with the given
 | 
			
		||||
// array position can be safely represented inside a JSON string, embedded
 | 
			
		||||
// inside of HTML <script> tags, without any additional escaping.
 | 
			
		||||
//
 | 
			
		||||
// All values are true except for the ASCII control characters (0-31), the
 | 
			
		||||
// double quote ("), the backslash character ("\"), HTML opening and closing
 | 
			
		||||
// tags ("<" and ">"), and the ampersand ("&").
 | 
			
		||||
var htmlSafeSet = [utf8.RuneSelf]bool{
 | 
			
		||||
	' ':      true,
 | 
			
		||||
	'!':      true,
 | 
			
		||||
	'"':      false,
 | 
			
		||||
	'#':      true,
 | 
			
		||||
	'$':      true,
 | 
			
		||||
	'%':      true,
 | 
			
		||||
	'&':      false,
 | 
			
		||||
	'\'':     true,
 | 
			
		||||
	'(':      true,
 | 
			
		||||
	')':      true,
 | 
			
		||||
	'*':      true,
 | 
			
		||||
	'+':      true,
 | 
			
		||||
	',':      true,
 | 
			
		||||
	'-':      true,
 | 
			
		||||
	'.':      true,
 | 
			
		||||
	'/':      true,
 | 
			
		||||
	'0':      true,
 | 
			
		||||
	'1':      true,
 | 
			
		||||
	'2':      true,
 | 
			
		||||
	'3':      true,
 | 
			
		||||
	'4':      true,
 | 
			
		||||
	'5':      true,
 | 
			
		||||
	'6':      true,
 | 
			
		||||
	'7':      true,
 | 
			
		||||
	'8':      true,
 | 
			
		||||
	'9':      true,
 | 
			
		||||
	':':      true,
 | 
			
		||||
	';':      true,
 | 
			
		||||
	'<':      false,
 | 
			
		||||
	'=':      true,
 | 
			
		||||
	'>':      false,
 | 
			
		||||
	'?':      true,
 | 
			
		||||
	'@':      true,
 | 
			
		||||
	'A':      true,
 | 
			
		||||
	'B':      true,
 | 
			
		||||
	'C':      true,
 | 
			
		||||
	'D':      true,
 | 
			
		||||
	'E':      true,
 | 
			
		||||
	'F':      true,
 | 
			
		||||
	'G':      true,
 | 
			
		||||
	'H':      true,
 | 
			
		||||
	'I':      true,
 | 
			
		||||
	'J':      true,
 | 
			
		||||
	'K':      true,
 | 
			
		||||
	'L':      true,
 | 
			
		||||
	'M':      true,
 | 
			
		||||
	'N':      true,
 | 
			
		||||
	'O':      true,
 | 
			
		||||
	'P':      true,
 | 
			
		||||
	'Q':      true,
 | 
			
		||||
	'R':      true,
 | 
			
		||||
	'S':      true,
 | 
			
		||||
	'T':      true,
 | 
			
		||||
	'U':      true,
 | 
			
		||||
	'V':      true,
 | 
			
		||||
	'W':      true,
 | 
			
		||||
	'X':      true,
 | 
			
		||||
	'Y':      true,
 | 
			
		||||
	'Z':      true,
 | 
			
		||||
	'[':      true,
 | 
			
		||||
	'\\':     false,
 | 
			
		||||
	']':      true,
 | 
			
		||||
	'^':      true,
 | 
			
		||||
	'_':      true,
 | 
			
		||||
	'`':      true,
 | 
			
		||||
	'a':      true,
 | 
			
		||||
	'b':      true,
 | 
			
		||||
	'c':      true,
 | 
			
		||||
	'd':      true,
 | 
			
		||||
	'e':      true,
 | 
			
		||||
	'f':      true,
 | 
			
		||||
	'g':      true,
 | 
			
		||||
	'h':      true,
 | 
			
		||||
	'i':      true,
 | 
			
		||||
	'j':      true,
 | 
			
		||||
	'k':      true,
 | 
			
		||||
	'l':      true,
 | 
			
		||||
	'm':      true,
 | 
			
		||||
	'n':      true,
 | 
			
		||||
	'o':      true,
 | 
			
		||||
	'p':      true,
 | 
			
		||||
	'q':      true,
 | 
			
		||||
	'r':      true,
 | 
			
		||||
	's':      true,
 | 
			
		||||
	't':      true,
 | 
			
		||||
	'u':      true,
 | 
			
		||||
	'v':      true,
 | 
			
		||||
	'w':      true,
 | 
			
		||||
	'x':      true,
 | 
			
		||||
	'y':      true,
 | 
			
		||||
	'z':      true,
 | 
			
		||||
	'{':      true,
 | 
			
		||||
	'|':      true,
 | 
			
		||||
	'}':      true,
 | 
			
		||||
	'~':      true,
 | 
			
		||||
	'\u007f': true,
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/tags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/sigs.k8s.io/json/internal/golang/encoding/json/tags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
// Copyright 2011 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 (
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// tagOptions is the string following a comma in a struct field's "json"
 | 
			
		||||
// tag, or the empty string. It does not include the leading comma.
 | 
			
		||||
type tagOptions string
 | 
			
		||||
 | 
			
		||||
// parseTag splits a struct field's json tag into its name and
 | 
			
		||||
// comma-separated options.
 | 
			
		||||
func parseTag(tag string) (string, tagOptions) {
 | 
			
		||||
	tag, opt, _ := strings.Cut(tag, ",")
 | 
			
		||||
	return tag, tagOptions(opt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Contains reports whether a comma-separated list of options
 | 
			
		||||
// contains a particular substr flag. substr must be surrounded by a
 | 
			
		||||
// string boundary or commas.
 | 
			
		||||
func (o tagOptions) Contains(optionName string) bool {
 | 
			
		||||
	if len(o) == 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	s := string(o)
 | 
			
		||||
	for s != "" {
 | 
			
		||||
		var name string
 | 
			
		||||
		name, s, _ = strings.Cut(s, ",")
 | 
			
		||||
		if name == optionName {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user