k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/internal/third_party/go-json-experiment/json/arshal.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package json 6 7 import ( 8 "errors" 9 "io" 10 "reflect" 11 "sync" 12 ) 13 14 // MarshalOptions configures how Go data is serialized as JSON data. 15 // The zero value is equivalent to the default marshal settings. 16 type MarshalOptions struct { 17 requireKeyedLiterals 18 nonComparable 19 20 // Marshalers is a list of type-specific marshalers to use. 21 Marshalers *Marshalers 22 23 // StringifyNumbers specifies that numeric Go types should be serialized 24 // as a JSON string containing the equivalent JSON number value. 25 // 26 // According to RFC 8259, section 6, a JSON implementation may choose to 27 // limit the representation of a JSON number to an IEEE 754 binary64 value. 28 // This may cause decoders to lose precision for int64 and uint64 types. 29 // Escaping JSON numbers as a JSON string preserves the exact precision. 30 StringifyNumbers bool 31 32 // DiscardUnknownMembers specifies that marshaling should ignore any 33 // JSON object members stored in Go struct fields dedicated to storing 34 // unknown JSON object members. 35 DiscardUnknownMembers bool 36 37 // Deterministic specifies that the same input value will be serialized 38 // as the exact same output bytes. Different processes of 39 // the same program will serialize equal values to the same bytes, 40 // but different versions of the same program are not guaranteed 41 // to produce the exact same sequence of bytes. 42 Deterministic bool 43 44 // formatDepth is the depth at which we respect the format flag. 45 formatDepth int 46 // format is custom formatting for the value at the specified depth. 47 format string 48 } 49 50 // Marshal serializes a Go value as a []byte with default options. 51 // It is a thin wrapper over MarshalOptions.Marshal. 52 func Marshal(in any) (out []byte, err error) { 53 return MarshalOptions{}.Marshal(EncodeOptions{}, in) 54 } 55 56 // MarshalFull serializes a Go value into an io.Writer with default options. 57 // It is a thin wrapper over MarshalOptions.MarshalFull. 58 func MarshalFull(out io.Writer, in any) error { 59 return MarshalOptions{}.MarshalFull(EncodeOptions{}, out, in) 60 } 61 62 // Marshal serializes a Go value as a []byte according to the provided 63 // marshal and encode options. It does not terminate the output with a newline. 64 // See MarshalNext for details about the conversion of a Go value into JSON. 65 func (mo MarshalOptions) Marshal(eo EncodeOptions, in any) (out []byte, err error) { 66 enc := getBufferedEncoder(eo) 67 defer putBufferedEncoder(enc) 68 enc.options.omitTopLevelNewline = true 69 err = mo.MarshalNext(enc, in) 70 // TODO(https://go.dev/issue/45038): Use bytes.Clone. 71 return append([]byte(nil), enc.buf...), err 72 } 73 74 // MarshalFull serializes a Go value into an io.Writer according to the provided 75 // marshal and encode options. It does not terminate the output with a newline. 76 // See MarshalNext for details about the conversion of a Go value into JSON. 77 func (mo MarshalOptions) MarshalFull(eo EncodeOptions, out io.Writer, in any) error { 78 enc := getStreamingEncoder(out, eo) 79 defer putStreamingEncoder(enc) 80 enc.options.omitTopLevelNewline = true 81 err := mo.MarshalNext(enc, in) 82 return err 83 } 84 85 // MarshalNext encodes a Go value as the next JSON value according to 86 // the provided marshal options. 87 // 88 // Type-specific marshal functions and methods take precedence 89 // over the default representation of a value. 90 // Functions or methods that operate on *T are only called when encoding 91 // a value of type T (by taking its address) or a non-nil value of *T. 92 // MarshalNext ensures that a value is always addressable 93 // (by boxing it on the heap if necessary) so that 94 // these functions and methods can be consistently called. For performance, 95 // it is recommended that MarshalNext be passed a non-nil pointer to the value. 96 // 97 // The input value is encoded as JSON according the following rules: 98 // 99 // - If any type-specific functions in MarshalOptions.Marshalers match 100 // the value type, then those functions are called to encode the value. 101 // If all applicable functions return SkipFunc, 102 // then the value is encoded according to subsequent rules. 103 // 104 // - If the value type implements MarshalerV2, 105 // then the MarshalNextJSON method is called to encode the value. 106 // 107 // - If the value type implements MarshalerV1, 108 // then the MarshalJSON method is called to encode the value. 109 // 110 // - If the value type implements encoding.TextMarshaler, 111 // then the MarshalText method is called to encode the value and 112 // subsequently encode its result as a JSON string. 113 // 114 // - Otherwise, the value is encoded according to the value's type 115 // as described in detail below. 116 // 117 // Most Go types have a default JSON representation. 118 // Certain types support specialized formatting according to 119 // a format flag optionally specified in the Go struct tag 120 // for the struct field that contains the current value 121 // (see the “JSON Representation of Go structs” section for more details). 122 // 123 // The representation of each type is as follows: 124 // 125 // - A Go boolean is encoded as a JSON boolean (e.g., true or false). 126 // It does not support any custom format flags. 127 // 128 // - A Go string is encoded as a JSON string. 129 // It does not support any custom format flags. 130 // 131 // - A Go []byte or [N]byte is encoded as a JSON string containing 132 // the binary value encoded using RFC 4648. 133 // If the format is "base64" or unspecified, then this uses RFC 4648, section 4. 134 // If the format is "base64url", then this uses RFC 4648, section 5. 135 // If the format is "base32", then this uses RFC 4648, section 6. 136 // If the format is "base32hex", then this uses RFC 4648, section 7. 137 // If the format is "base16" or "hex", then this uses RFC 4648, section 8. 138 // If the format is "array", then the bytes value is encoded as a JSON array 139 // where each byte is recursively JSON-encoded as each JSON array element. 140 // 141 // - A Go integer is encoded as a JSON number without fractions or exponents. 142 // If MarshalOptions.StringifyNumbers is specified, then the JSON number is 143 // encoded within a JSON string. It does not support any custom format 144 // flags. 145 // 146 // - A Go float is encoded as a JSON number. 147 // If MarshalOptions.StringifyNumbers is specified, 148 // then the JSON number is encoded within a JSON string. 149 // If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as 150 // the JSON strings "NaN", "Infinity", and "-Infinity", respectively. 151 // Otherwise, the presence of non-finite numbers results in a SemanticError. 152 // 153 // - A Go map is encoded as a JSON object, where each Go map key and value 154 // is recursively encoded as a name and value pair in the JSON object. 155 // The Go map key must encode as a JSON string, otherwise this results 156 // in a SemanticError. When encoding keys, MarshalOptions.StringifyNumbers 157 // is automatically applied so that numeric keys encode as JSON strings. 158 // The Go map is traversed in a non-deterministic order. 159 // For deterministic encoding, consider using RawValue.Canonicalize. 160 // If the format is "emitnull", then a nil map is encoded as a JSON null. 161 // Otherwise by default, a nil map is encoded as an empty JSON object. 162 // 163 // - A Go struct is encoded as a JSON object. 164 // See the “JSON Representation of Go structs” section 165 // in the package-level documentation for more details. 166 // 167 // - A Go slice is encoded as a JSON array, where each Go slice element 168 // is recursively JSON-encoded as the elements of the JSON array. 169 // If the format is "emitnull", then a nil slice is encoded as a JSON null. 170 // Otherwise by default, a nil slice is encoded as an empty JSON array. 171 // 172 // - A Go array is encoded as a JSON array, where each Go array element 173 // is recursively JSON-encoded as the elements of the JSON array. 174 // The JSON array length is always identical to the Go array length. 175 // It does not support any custom format flags. 176 // 177 // - A Go pointer is encoded as a JSON null if nil, otherwise it is 178 // the recursively JSON-encoded representation of the underlying value. 179 // Format flags are forwarded to the encoding of the underlying value. 180 // 181 // - A Go interface is encoded as a JSON null if nil, otherwise it is 182 // the recursively JSON-encoded representation of the underlying value. 183 // It does not support any custom format flags. 184 // 185 // - A Go time.Time is encoded as a JSON string containing the timestamp 186 // formatted in RFC 3339 with nanosecond resolution. 187 // If the format matches one of the format constants declared 188 // in the time package (e.g., RFC1123), then that format is used. 189 // Otherwise, the format is used as-is with time.Time.Format if non-empty. 190 // 191 // - A Go time.Duration is encoded as a JSON string containing the duration 192 // formatted according to time.Duration.String. 193 // If the format is "nanos", it is encoded as a JSON number 194 // containing the number of nanoseconds in the duration. 195 // 196 // - All other Go types (e.g., complex numbers, channels, and functions) 197 // have no default representation and result in a SemanticError. 198 // 199 // JSON cannot represent cyclic data structures and 200 // MarshalNext does not handle them. 201 // Passing cyclic structures will result in an error. 202 func (mo MarshalOptions) MarshalNext(out *Encoder, in any) error { 203 v := reflect.ValueOf(in) 204 if !v.IsValid() || (v.Kind() == reflect.Pointer && v.IsNil()) { 205 return out.WriteToken(Null) 206 } 207 // Shallow copy non-pointer values to obtain an addressable value. 208 // It is beneficial to performance to always pass pointers to avoid this. 209 if v.Kind() != reflect.Pointer { 210 v2 := reflect.New(v.Type()) 211 v2.Elem().Set(v) 212 v = v2 213 } 214 va := addressableValue{v.Elem()} // dereferenced pointer is always addressable 215 t := va.Type() 216 217 // Lookup and call the marshal function for this type. 218 marshal := lookupArshaler(t).marshal 219 if mo.Marshalers != nil { 220 marshal, _ = mo.Marshalers.lookup(marshal, t) 221 } 222 if err := marshal(mo, out, va); err != nil { 223 if !out.options.AllowDuplicateNames { 224 out.tokens.invalidateDisabledNamespaces() 225 } 226 return err 227 } 228 return nil 229 } 230 231 // UnmarshalOptions configures how JSON data is deserialized as Go data. 232 // The zero value is equivalent to the default unmarshal settings. 233 type UnmarshalOptions struct { 234 requireKeyedLiterals 235 nonComparable 236 237 // Unmarshalers is a list of type-specific unmarshalers to use. 238 Unmarshalers *Unmarshalers 239 240 // StringifyNumbers specifies that numeric Go types can be deserialized 241 // from either a JSON number or a JSON string containing a JSON number 242 // without any surrounding whitespace. 243 StringifyNumbers bool 244 245 // RejectUnknownMembers specifies that unknown members should be rejected 246 // when unmarshaling a JSON object, regardless of whether there is a field 247 // to store unknown members. 248 RejectUnknownMembers bool 249 250 // formatDepth is the depth at which we respect the format flag. 251 formatDepth int 252 // format is custom formatting for the value at the specified depth. 253 format string 254 } 255 256 // Unmarshal deserializes a Go value from a []byte with default options. 257 // It is a thin wrapper over UnmarshalOptions.Unmarshal. 258 func Unmarshal(in []byte, out any) error { 259 return UnmarshalOptions{}.Unmarshal(DecodeOptions{}, in, out) 260 } 261 262 // UnmarshalFull deserializes a Go value from an io.Reader with default options. 263 // It is a thin wrapper over UnmarshalOptions.UnmarshalFull. 264 func UnmarshalFull(in io.Reader, out any) error { 265 return UnmarshalOptions{}.UnmarshalFull(DecodeOptions{}, in, out) 266 } 267 268 // Unmarshal deserializes a Go value from a []byte according to the 269 // provided unmarshal and decode options. The output must be a non-nil pointer. 270 // The input must be a single JSON value with optional whitespace interspersed. 271 // See UnmarshalNext for details about the conversion of JSON into a Go value. 272 func (uo UnmarshalOptions) Unmarshal(do DecodeOptions, in []byte, out any) error { 273 dec := getBufferedDecoder(in, do) 274 defer putBufferedDecoder(dec) 275 return uo.unmarshalFull(dec, out) 276 } 277 278 // UnmarshalFull deserializes a Go value from an io.Reader according to the 279 // provided unmarshal and decode options. The output must be a non-nil pointer. 280 // The input must be a single JSON value with optional whitespace interspersed. 281 // It consumes the entirety of io.Reader until io.EOF is encountered. 282 // See UnmarshalNext for details about the conversion of JSON into a Go value. 283 func (uo UnmarshalOptions) UnmarshalFull(do DecodeOptions, in io.Reader, out any) error { 284 dec := getStreamingDecoder(in, do) 285 defer putStreamingDecoder(dec) 286 return uo.unmarshalFull(dec, out) 287 } 288 func (uo UnmarshalOptions) unmarshalFull(in *Decoder, out any) error { 289 switch err := uo.UnmarshalNext(in, out); err { 290 case nil: 291 return in.checkEOF() 292 case io.EOF: 293 return io.ErrUnexpectedEOF 294 default: 295 return err 296 } 297 } 298 299 // UnmarshalNext decodes the next JSON value into a Go value according to 300 // the provided unmarshal options. The output must be a non-nil pointer. 301 // 302 // Type-specific unmarshal functions and methods take precedence 303 // over the default representation of a value. 304 // Functions or methods that operate on *T are only called when decoding 305 // a value of type T (by taking its address) or a non-nil value of *T. 306 // UnmarshalNext ensures that a value is always addressable 307 // (by boxing it on the heap if necessary) so that 308 // these functions and methods can be consistently called. 309 // 310 // The input is decoded into the output according the following rules: 311 // 312 // - If any type-specific functions in UnmarshalOptions.Unmarshalers match 313 // the value type, then those functions are called to decode the JSON 314 // value. If all applicable functions return SkipFunc, 315 // then the input is decoded according to subsequent rules. 316 // 317 // - If the value type implements UnmarshalerV2, 318 // then the UnmarshalNextJSON method is called to decode the JSON value. 319 // 320 // - If the value type implements UnmarshalerV1, 321 // then the UnmarshalJSON method is called to decode the JSON value. 322 // 323 // - If the value type implements encoding.TextUnmarshaler, 324 // then the input is decoded as a JSON string and 325 // the UnmarshalText method is called with the decoded string value. 326 // This fails with a SemanticError if the input is not a JSON string. 327 // 328 // - Otherwise, the JSON value is decoded according to the value's type 329 // as described in detail below. 330 // 331 // Most Go types have a default JSON representation. 332 // Certain types support specialized formatting according to 333 // a format flag optionally specified in the Go struct tag 334 // for the struct field that contains the current value 335 // (see the “JSON Representation of Go structs” section for more details). 336 // A JSON null may be decoded into every supported Go value where 337 // it is equivalent to storing the zero value of the Go value. 338 // If the input JSON kind is not handled by the current Go value type, 339 // then this fails with a SemanticError. Unless otherwise specified, 340 // the decoded value replaces any pre-existing value. 341 // 342 // The representation of each type is as follows: 343 // 344 // - A Go boolean is decoded from a JSON boolean (e.g., true or false). 345 // It does not support any custom format flags. 346 // 347 // - A Go string is decoded from a JSON string. 348 // It does not support any custom format flags. 349 // 350 // - A Go []byte or [N]byte is decoded from a JSON string 351 // containing the binary value encoded using RFC 4648. 352 // If the format is "base64" or unspecified, then this uses RFC 4648, section 4. 353 // If the format is "base64url", then this uses RFC 4648, section 5. 354 // If the format is "base32", then this uses RFC 4648, section 6. 355 // If the format is "base32hex", then this uses RFC 4648, section 7. 356 // If the format is "base16" or "hex", then this uses RFC 4648, section 8. 357 // If the format is "array", then the Go slice or array is decoded from a 358 // JSON array where each JSON element is recursively decoded for each byte. 359 // When decoding into a non-nil []byte, the slice length is reset to zero 360 // and the decoded input is appended to it. 361 // When decoding into a [N]byte, the input must decode to exactly N bytes, 362 // otherwise it fails with a SemanticError. 363 // 364 // - A Go integer is decoded from a JSON number. 365 // It may also be decoded from a JSON string containing a JSON number 366 // if UnmarshalOptions.StringifyNumbers is specified. 367 // It fails with a SemanticError if the JSON number 368 // has a fractional or exponent component. 369 // It also fails if it overflows the representation of the Go integer type. 370 // It does not support any custom format flags. 371 // 372 // - A Go float is decoded from a JSON number. 373 // It may also be decoded from a JSON string containing a JSON number 374 // if UnmarshalOptions.StringifyNumbers is specified. 375 // The JSON number is parsed as the closest representable Go float value. 376 // If the format is "nonfinite", then the JSON strings 377 // "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf. 378 // Otherwise, the presence of such strings results in a SemanticError. 379 // 380 // - A Go map is decoded from a JSON object, 381 // where each JSON object name and value pair is recursively decoded 382 // as the Go map key and value. When decoding keys, 383 // UnmarshalOptions.StringifyNumbers is automatically applied so that 384 // numeric keys can decode from JSON strings. Maps are not cleared. 385 // If the Go map is nil, then a new map is allocated to decode into. 386 // If the decoded key matches an existing Go map entry, the entry value 387 // is reused by decoding the JSON object value into it. 388 // The only supported format is "emitnull" and has no effect when decoding. 389 // 390 // - A Go struct is decoded from a JSON object. 391 // See the “JSON Representation of Go structs” section 392 // in the package-level documentation for more details. 393 // 394 // - A Go slice is decoded from a JSON array, where each JSON element 395 // is recursively decoded and appended to the Go slice. 396 // Before appending into a Go slice, a new slice is allocated if it is nil, 397 // otherwise the slice length is reset to zero. 398 // The only supported format is "emitnull" and has no effect when decoding. 399 // 400 // - A Go array is decoded from a JSON array, where each JSON array element 401 // is recursively decoded as each corresponding Go array element. 402 // Each Go array element is zeroed before decoding into it. 403 // It fails with a SemanticError if the JSON array does not contain 404 // the exact same number of elements as the Go array. 405 // It does not support any custom format flags. 406 // 407 // - A Go pointer is decoded based on the JSON kind and underlying Go type. 408 // If the input is a JSON null, then this stores a nil pointer. 409 // Otherwise, it allocates a new underlying value if the pointer is nil, 410 // and recursively JSON decodes into the underlying value. 411 // Format flags are forwarded to the decoding of the underlying type. 412 // 413 // - A Go interface is decoded based on the JSON kind and underlying Go type. 414 // If the input is a JSON null, then this stores a nil interface value. 415 // Otherwise, a nil interface value of an empty interface type is initialized 416 // with a zero Go bool, string, float64, map[string]any, or []any if the 417 // input is a JSON boolean, string, number, object, or array, respectively. 418 // If the interface value is still nil, then this fails with a SemanticError 419 // since decoding could not determine an appropriate Go type to decode into. 420 // For example, unmarshaling into a nil io.Reader fails since 421 // there is no concrete type to populate the interface value with. 422 // Otherwise an underlying value exists and it recursively decodes 423 // the JSON input into it. It does not support any custom format flags. 424 // 425 // - A Go time.Time is decoded from a JSON string containing the time 426 // formatted in RFC 3339 with nanosecond resolution. 427 // If the format matches one of the format constants declared in 428 // the time package (e.g., RFC1123), then that format is used for parsing. 429 // Otherwise, the format is used as-is with time.Time.Parse if non-empty. 430 // 431 // - A Go time.Duration is decoded from a JSON string by 432 // passing the decoded string to time.ParseDuration. 433 // If the format is "nanos", it is instead decoded from a JSON number 434 // containing the number of nanoseconds in the duration. 435 // 436 // - All other Go types (e.g., complex numbers, channels, and functions) 437 // have no default representation and result in a SemanticError. 438 // 439 // In general, unmarshaling follows merge semantics (similar to RFC 7396) 440 // where the decoded Go value replaces the destination value 441 // for any JSON kind other than an object. 442 // For JSON objects, the input object is merged into the destination value 443 // where matching object members recursively apply merge semantics. 444 func (uo UnmarshalOptions) UnmarshalNext(in *Decoder, out any) error { 445 v := reflect.ValueOf(out) 446 if !v.IsValid() || v.Kind() != reflect.Pointer || v.IsNil() { 447 var t reflect.Type 448 if v.IsValid() { 449 t = v.Type() 450 if t.Kind() == reflect.Pointer { 451 t = t.Elem() 452 } 453 } 454 err := errors.New("value must be passed as a non-nil pointer reference") 455 return &SemanticError{action: "unmarshal", GoType: t, Err: err} 456 } 457 va := addressableValue{v.Elem()} // dereferenced pointer is always addressable 458 t := va.Type() 459 460 // Lookup and call the unmarshal function for this type. 461 unmarshal := lookupArshaler(t).unmarshal 462 if uo.Unmarshalers != nil { 463 unmarshal, _ = uo.Unmarshalers.lookup(unmarshal, t) 464 } 465 if err := unmarshal(uo, in, va); err != nil { 466 if !in.options.AllowDuplicateNames { 467 in.tokens.invalidateDisabledNamespaces() 468 } 469 return err 470 } 471 return nil 472 } 473 474 // addressableValue is a reflect.Value that is guaranteed to be addressable 475 // such that calling the Addr and Set methods do not panic. 476 // 477 // There is no compile magic that enforces this property, 478 // but rather the need to construct this type makes it easier to examine each 479 // construction site to ensure that this property is upheld. 480 type addressableValue struct{ reflect.Value } 481 482 // newAddressableValue constructs a new addressable value of type t. 483 func newAddressableValue(t reflect.Type) addressableValue { 484 return addressableValue{reflect.New(t).Elem()} 485 } 486 487 // All marshal and unmarshal behavior is implemented using these signatures. 488 type ( 489 marshaler = func(MarshalOptions, *Encoder, addressableValue) error 490 unmarshaler = func(UnmarshalOptions, *Decoder, addressableValue) error 491 ) 492 493 type arshaler struct { 494 marshal marshaler 495 unmarshal unmarshaler 496 nonDefault bool 497 } 498 499 var lookupArshalerCache sync.Map // map[reflect.Type]*arshaler 500 501 func lookupArshaler(t reflect.Type) *arshaler { 502 if v, ok := lookupArshalerCache.Load(t); ok { 503 return v.(*arshaler) 504 } 505 506 fncs := makeDefaultArshaler(t) 507 fncs = makeMethodArshaler(fncs, t) 508 fncs = makeTimeArshaler(fncs, t) 509 510 // Use the last stored so that duplicate arshalers can be garbage collected. 511 v, _ := lookupArshalerCache.LoadOrStore(t, fncs) 512 return v.(*arshaler) 513 }