k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/internal/third_party/go-json-experiment/json/arshal_funcs.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 "fmt" 10 "reflect" 11 "sync" 12 ) 13 14 // SkipFunc may be returned by MarshalFuncV2 and UnmarshalFuncV2 functions. 15 // 16 // Any function that returns SkipFunc must not cause observable side effects 17 // on the provided Encoder or Decoder. For example, it is permissible to call 18 // Decoder.PeekKind, but not permissible to call Decoder.ReadToken or 19 // Encoder.WriteToken since such methods mutate the state. 20 const SkipFunc = jsonError("skip function") 21 22 // Marshalers is a list of functions that may override the marshal behavior 23 // of specific types. Populate MarshalOptions.Marshalers to use it. 24 // A nil *Marshalers is equivalent to an empty list. 25 type Marshalers = typedMarshalers 26 27 // NewMarshalers constructs a flattened list of marshal functions. 28 // If multiple functions in the list are applicable for a value of a given type, 29 // then those earlier in the list take precedence over those that come later. 30 // If a function returns SkipFunc, then the next applicable function is called, 31 // otherwise the default marshaling behavior is used. 32 // 33 // For example: 34 // 35 // m1 := NewMarshalers(f1, f2) 36 // m2 := NewMarshalers(f0, m1, f3) // equivalent to m3 37 // m3 := NewMarshalers(f0, f1, f2, f3) // equivalent to m2 38 func NewMarshalers(ms ...*Marshalers) *Marshalers { 39 return newMarshalers(ms...) 40 } 41 42 // Unmarshalers is a list of functions that may override the unmarshal behavior 43 // of specific types. Populate UnmarshalOptions.Unmarshalers to use it. 44 // A nil *Unmarshalers is equivalent to an empty list. 45 type Unmarshalers = typedUnmarshalers 46 47 // NewUnmarshalers constructs a flattened list of unmarshal functions. 48 // If multiple functions in the list are applicable for a value of a given type, 49 // then those earlier in the list take precedence over those that come later. 50 // If a function returns SkipFunc, then the next applicable function is called, 51 // otherwise the default unmarshaling behavior is used. 52 // 53 // For example: 54 // 55 // u1 := NewUnmarshalers(f1, f2) 56 // u2 := NewUnmarshalers(f0, u1, f3) // equivalent to u3 57 // u3 := NewUnmarshalers(f0, f1, f2, f3) // equivalent to u2 58 func NewUnmarshalers(us ...*Unmarshalers) *Unmarshalers { 59 return newUnmarshalers(us...) 60 } 61 62 type typedMarshalers = typedArshalers[MarshalOptions, Encoder] 63 type typedUnmarshalers = typedArshalers[UnmarshalOptions, Decoder] 64 type typedArshalers[Options, Coder any] struct { 65 nonComparable 66 67 fncVals []typedArshaler[Options, Coder] 68 fncCache sync.Map // map[reflect.Type]arshaler 69 70 // fromAny reports whether any of Go types used to represent arbitrary JSON 71 // (i.e., any, bool, string, float64, map[string]any, or []any) matches 72 // any of the provided type-specific arshalers. 73 // 74 // This bit of information is needed in arshal_default.go to determine 75 // whether to use the specialized logic in arshal_any.go to handle 76 // the any interface type. The logic in arshal_any.go does not support 77 // type-specific arshal functions, so we must avoid using that logic 78 // if this is true. 79 fromAny bool 80 } 81 type typedMarshaler = typedArshaler[MarshalOptions, Encoder] 82 type typedUnmarshaler = typedArshaler[UnmarshalOptions, Decoder] 83 type typedArshaler[Options, Coder any] struct { 84 typ reflect.Type 85 fnc func(Options, *Coder, addressableValue) error 86 maySkip bool 87 } 88 89 func newMarshalers(ms ...*Marshalers) *Marshalers { return newTypedArshalers(ms...) } 90 func newUnmarshalers(us ...*Unmarshalers) *Unmarshalers { return newTypedArshalers(us...) } 91 func newTypedArshalers[Options, Coder any](as ...*typedArshalers[Options, Coder]) *typedArshalers[Options, Coder] { 92 var a typedArshalers[Options, Coder] 93 for _, a2 := range as { 94 if a2 != nil { 95 a.fncVals = append(a.fncVals, a2.fncVals...) 96 a.fromAny = a.fromAny || a2.fromAny 97 } 98 } 99 if len(a.fncVals) == 0 { 100 return nil 101 } 102 return &a 103 } 104 105 func (a *typedArshalers[Options, Coder]) lookup(fnc func(Options, *Coder, addressableValue) error, t reflect.Type) (func(Options, *Coder, addressableValue) error, bool) { 106 if a == nil { 107 return fnc, false 108 } 109 if v, ok := a.fncCache.Load(t); ok { 110 if v == nil { 111 return fnc, false 112 } 113 return v.(func(Options, *Coder, addressableValue) error), true 114 } 115 116 // Collect a list of arshalers that can be called for this type. 117 // This list may be longer than 1 since some arshalers can be skipped. 118 var fncs []func(Options, *Coder, addressableValue) error 119 for _, fncVal := range a.fncVals { 120 if !castableTo(t, fncVal.typ) { 121 continue 122 } 123 fncs = append(fncs, fncVal.fnc) 124 if !fncVal.maySkip { 125 break // subsequent arshalers will never be called 126 } 127 } 128 129 if len(fncs) == 0 { 130 a.fncCache.Store(t, nil) // nil to indicate that no funcs found 131 return fnc, false 132 } 133 134 // Construct an arshaler that may call every applicable arshaler. 135 fncDefault := fnc 136 fnc = func(o Options, c *Coder, v addressableValue) error { 137 for _, fnc := range fncs { 138 if err := fnc(o, c, v); err != SkipFunc { 139 return err // may be nil or non-nil 140 } 141 } 142 return fncDefault(o, c, v) 143 } 144 145 // Use the first stored so duplicate work can be garbage collected. 146 v, _ := a.fncCache.LoadOrStore(t, fnc) 147 return v.(func(Options, *Coder, addressableValue) error), true 148 } 149 150 // MarshalFuncV1 constructs a type-specific marshaler that 151 // specifies how to marshal values of type T. 152 // T can be any type except a named pointer. 153 // The function is always provided with a non-nil pointer value 154 // if T is an interface or pointer type. 155 // 156 // The function must marshal exactly one JSON value. 157 // The value of T must not be retained outside the function call. 158 // It may not return SkipFunc. 159 func MarshalFuncV1[T any](fn func(T) ([]byte, error)) *Marshalers { 160 t := reflect.TypeOf((*T)(nil)).Elem() 161 assertCastableTo(t, true) 162 typFnc := typedMarshaler{ 163 typ: t, 164 fnc: func(mo MarshalOptions, enc *Encoder, va addressableValue) error { 165 val, err := fn(va.castTo(t).Interface().(T)) 166 if err != nil { 167 err = wrapSkipFunc(err, "marshal function of type func(T) ([]byte, error)") 168 // TODO: Avoid wrapping semantic errors. 169 return &SemanticError{action: "marshal", GoType: t, Err: err} 170 } 171 if err := enc.WriteValue(val); err != nil { 172 // TODO: Avoid wrapping semantic or I/O errors. 173 return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err} 174 } 175 return nil 176 }, 177 } 178 return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)} 179 } 180 181 // MarshalFuncV2 constructs a type-specific marshaler that 182 // specifies how to marshal values of type T. 183 // T can be any type except a named pointer. 184 // The function is always provided with a non-nil pointer value 185 // if T is an interface or pointer type. 186 // 187 // The function must marshal exactly one JSON value by calling write methods 188 // on the provided encoder. It may return SkipFunc such that marshaling can 189 // move on to the next marshal function. However, no mutable method calls may 190 // be called on the encoder if SkipFunc is returned. 191 // The pointer to Encoder and the value of T must not be retained 192 // outside the function call. 193 func MarshalFuncV2[T any](fn func(MarshalOptions, *Encoder, T) error) *Marshalers { 194 t := reflect.TypeOf((*T)(nil)).Elem() 195 assertCastableTo(t, true) 196 typFnc := typedMarshaler{ 197 typ: t, 198 fnc: func(mo MarshalOptions, enc *Encoder, va addressableValue) error { 199 prevDepth, prevLength := enc.tokens.depthLength() 200 err := fn(mo, enc, va.castTo(t).Interface().(T)) 201 currDepth, currLength := enc.tokens.depthLength() 202 if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { 203 err = errors.New("must write exactly one JSON value") 204 } 205 if err != nil { 206 if err == SkipFunc { 207 if prevDepth == currDepth && prevLength == currLength { 208 return SkipFunc 209 } 210 err = errors.New("must not write any JSON tokens when skipping") 211 } 212 // TODO: Avoid wrapping semantic or I/O errors. 213 return &SemanticError{action: "marshal", GoType: t, Err: err} 214 } 215 return nil 216 }, 217 maySkip: true, 218 } 219 return &Marshalers{fncVals: []typedMarshaler{typFnc}, fromAny: castableToFromAny(t)} 220 } 221 222 // UnmarshalFuncV1 constructs a type-specific unmarshaler that 223 // specifies how to unmarshal values of type T. 224 // T must be an unnamed pointer or an interface type. 225 // The function is always provided with a non-nil pointer value. 226 // 227 // The function must unmarshal exactly one JSON value. 228 // The input []byte must not be mutated. 229 // The input []byte and value T must not be retained outside the function call. 230 // It may not return SkipFunc. 231 func UnmarshalFuncV1[T any](fn func([]byte, T) error) *Unmarshalers { 232 t := reflect.TypeOf((*T)(nil)).Elem() 233 assertCastableTo(t, false) 234 typFnc := typedUnmarshaler{ 235 typ: t, 236 fnc: func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { 237 val, err := dec.ReadValue() 238 if err != nil { 239 return err // must be a syntactic or I/O error 240 } 241 err = fn(val, va.castTo(t).Interface().(T)) 242 if err != nil { 243 err = wrapSkipFunc(err, "unmarshal function of type func([]byte, T) error") 244 // TODO: Avoid wrapping semantic, syntactic, or I/O errors. 245 return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err} 246 } 247 return nil 248 }, 249 } 250 return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)} 251 } 252 253 // UnmarshalFuncV2 constructs a type-specific unmarshaler that 254 // specifies how to unmarshal values of type T. 255 // T must be an unnamed pointer or an interface type. 256 // The function is always provided with a non-nil pointer value. 257 // 258 // The function must unmarshal exactly one JSON value by calling read methods 259 // on the provided decoder. It may return SkipFunc such that unmarshaling can 260 // move on to the next unmarshal function. However, no mutable method calls may 261 // be called on the decoder if SkipFunc is returned. 262 // The pointer to Decoder and the value of T must not be retained 263 // outside the function call. 264 func UnmarshalFuncV2[T any](fn func(UnmarshalOptions, *Decoder, T) error) *Unmarshalers { 265 t := reflect.TypeOf((*T)(nil)).Elem() 266 assertCastableTo(t, false) 267 typFnc := typedUnmarshaler{ 268 typ: t, 269 fnc: func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { 270 prevDepth, prevLength := dec.tokens.depthLength() 271 err := fn(uo, dec, va.castTo(t).Interface().(T)) 272 currDepth, currLength := dec.tokens.depthLength() 273 if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { 274 err = errors.New("must read exactly one JSON value") 275 } 276 if err != nil { 277 if err == SkipFunc { 278 if prevDepth == currDepth && prevLength == currLength { 279 return SkipFunc 280 } 281 err = errors.New("must not read any JSON tokens when skipping") 282 } 283 // TODO: Avoid wrapping semantic, syntactic, or I/O errors. 284 return &SemanticError{action: "unmarshal", GoType: t, Err: err} 285 } 286 return nil 287 }, 288 maySkip: true, 289 } 290 return &Unmarshalers{fncVals: []typedUnmarshaler{typFnc}, fromAny: castableToFromAny(t)} 291 } 292 293 // assertCastableTo asserts that "to" is a valid type to be casted to. 294 // These are the Go types that type-specific arshalers may operate upon. 295 // 296 // Let AllTypes be the universal set of all possible Go types. 297 // This function generally asserts that: 298 // 299 // len([from for from in AllTypes if castableTo(from, to)]) > 0 300 // 301 // otherwise it panics. 302 // 303 // As a special-case if marshal is false, then we forbid any non-pointer or 304 // non-interface type since it is almost always a bug trying to unmarshal 305 // into something where the end-user caller did not pass in an addressable value 306 // since they will not observe the mutations. 307 func assertCastableTo(to reflect.Type, marshal bool) { 308 switch to.Kind() { 309 case reflect.Interface: 310 return 311 case reflect.Pointer: 312 // Only allow unnamed pointers to be consistent with the fact that 313 // taking the address of a value produces an unnamed pointer type. 314 if to.Name() == "" { 315 return 316 } 317 default: 318 // Technically, non-pointer types are permissible for unmarshal. 319 // However, they are often a bug since the receiver would be immutable. 320 // Thus, only allow them for marshaling. 321 if marshal { 322 return 323 } 324 } 325 if marshal { 326 panic(fmt.Sprintf("input type %v must be an interface type, an unnamed pointer type, or a non-pointer type", to)) 327 } else { 328 panic(fmt.Sprintf("input type %v must be an interface type or an unnamed pointer type", to)) 329 } 330 } 331 332 // castableTo checks whether values of type "from" can be casted to type "to". 333 // Nil pointer or interface "from" values are never considered castable. 334 // 335 // This function must be kept in sync with addressableValue.castTo. 336 func castableTo(from, to reflect.Type) bool { 337 switch to.Kind() { 338 case reflect.Interface: 339 // TODO: This breaks when ordinary interfaces can have type sets 340 // since interfaces now exist where only the value form of a type (T) 341 // implements the interface, but not the pointer variant (*T). 342 // See https://go.dev/issue/45346. 343 return reflect.PointerTo(from).Implements(to) 344 case reflect.Pointer: 345 // Common case for unmarshaling. 346 // From must be a concrete or interface type. 347 return reflect.PointerTo(from) == to 348 default: 349 // Common case for marshaling. 350 // From must be a concrete type. 351 return from == to 352 } 353 } 354 355 // castTo casts va to the specified type. 356 // If the type is an interface, then the underlying type will always 357 // be a non-nil pointer to a concrete type. 358 // 359 // Requirement: castableTo(va.Type(), to) must hold. 360 func (va addressableValue) castTo(to reflect.Type) reflect.Value { 361 switch to.Kind() { 362 case reflect.Interface: 363 return va.Addr().Convert(to) 364 case reflect.Pointer: 365 return va.Addr() 366 default: 367 return va.Value 368 } 369 } 370 371 // castableToFromAny reports whether "to" can be casted to from any 372 // of the dynamic types used to represent arbitrary JSON. 373 func castableToFromAny(to reflect.Type) bool { 374 for _, from := range []reflect.Type{anyType, boolType, stringType, float64Type, mapStringAnyType, sliceAnyType} { 375 if castableTo(from, to) { 376 return true 377 } 378 } 379 return false 380 } 381 382 func wrapSkipFunc(err error, what string) error { 383 if err == SkipFunc { 384 return errors.New(what + " cannot be skipped") 385 } 386 return err 387 }