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  }