k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/internal/third_party/go-json-experiment/json/arshal_methods.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  	"encoding"
     9  	"errors"
    10  	"reflect"
    11  )
    12  
    13  // Interfaces for custom serialization.
    14  var (
    15  	jsonMarshalerV1Type   = reflect.TypeOf((*MarshalerV1)(nil)).Elem()
    16  	jsonMarshalerV2Type   = reflect.TypeOf((*MarshalerV2)(nil)).Elem()
    17  	jsonUnmarshalerV1Type = reflect.TypeOf((*UnmarshalerV1)(nil)).Elem()
    18  	jsonUnmarshalerV2Type = reflect.TypeOf((*UnmarshalerV2)(nil)).Elem()
    19  	textMarshalerType     = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
    20  	textUnmarshalerType   = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
    21  )
    22  
    23  // MarshalerV1 is implemented by types that can marshal themselves.
    24  // It is recommended that types implement MarshalerV2 unless the implementation
    25  // is trying to avoid a hard dependency on the "jsontext" package.
    26  //
    27  // It is recommended that implementations return a buffer that is safe
    28  // for the caller to retain and potentially mutate.
    29  type MarshalerV1 interface {
    30  	MarshalJSON() ([]byte, error)
    31  }
    32  
    33  // MarshalerV2 is implemented by types that can marshal themselves.
    34  // It is recommended that types implement MarshalerV2 instead of MarshalerV1
    35  // since this is both more performant and flexible.
    36  // If a type implements both MarshalerV1 and MarshalerV2,
    37  // then MarshalerV2 takes precedence. In such a case, both implementations
    38  // should aim to have equivalent behavior for the default marshal options.
    39  //
    40  // The implementation must write only one JSON value to the Encoder and
    41  // must not retain the pointer to Encoder.
    42  type MarshalerV2 interface {
    43  	MarshalNextJSON(MarshalOptions, *Encoder) error
    44  
    45  	// TODO: Should users call the MarshalOptions.MarshalNext method or
    46  	// should/can they call this method directly? Does it matter?
    47  }
    48  
    49  // UnmarshalerV1 is implemented by types that can unmarshal themselves.
    50  // It is recommended that types implement UnmarshalerV2 unless
    51  // the implementation is trying to avoid a hard dependency on this package.
    52  //
    53  // The input can be assumed to be a valid encoding of a JSON value
    54  // if called from unmarshal functionality in this package.
    55  // UnmarshalJSON must copy the JSON data if it is retained after returning.
    56  // It is recommended that UnmarshalJSON implement merge semantics when
    57  // unmarshaling into a pre-populated value.
    58  //
    59  // Implementations must not retain or mutate the input []byte.
    60  type UnmarshalerV1 interface {
    61  	UnmarshalJSON([]byte) error
    62  }
    63  
    64  // UnmarshalerV2 is implemented by types that can unmarshal themselves.
    65  // It is recommended that types implement UnmarshalerV2 instead of UnmarshalerV1
    66  // since this is both more performant and flexible.
    67  // If a type implements both UnmarshalerV1 and UnmarshalerV2,
    68  // then UnmarshalerV2 takes precedence. In such a case, both implementations
    69  // should aim to have equivalent behavior for the default unmarshal options.
    70  //
    71  // The implementation must read only one JSON value from the Decoder.
    72  // It is recommended that UnmarshalNextJSON implement merge semantics when
    73  // unmarshaling into a pre-populated value.
    74  //
    75  // Implementations must not retain the pointer to Decoder.
    76  type UnmarshalerV2 interface {
    77  	UnmarshalNextJSON(UnmarshalOptions, *Decoder) error
    78  
    79  	// TODO: Should users call the UnmarshalOptions.UnmarshalNext method or
    80  	// should/can they call this method directly? Does it matter?
    81  }
    82  
    83  func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler {
    84  	// Avoid injecting method arshaler on the pointer or interface version
    85  	// to avoid ever calling the method on a nil pointer or interface receiver.
    86  	// Let it be injected on the value receiver (which is always addressable).
    87  	if t.Kind() == reflect.Pointer || t.Kind() == reflect.Interface {
    88  		return fncs
    89  	}
    90  
    91  	// Handle custom marshaler.
    92  	switch which, needAddr := implementsWhich(t, jsonMarshalerV2Type, jsonMarshalerV1Type, textMarshalerType); which {
    93  	case jsonMarshalerV2Type:
    94  		fncs.nonDefault = true
    95  		fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
    96  			prevDepth, prevLength := enc.tokens.depthLength()
    97  			err := va.addrWhen(needAddr).Interface().(MarshalerV2).MarshalNextJSON(mo, enc)
    98  			currDepth, currLength := enc.tokens.depthLength()
    99  			if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil {
   100  				err = errors.New("must write exactly one JSON value")
   101  			}
   102  			if err != nil {
   103  				err = wrapSkipFunc(err, "marshal method")
   104  				// TODO: Avoid wrapping semantic or I/O errors.
   105  				return &SemanticError{action: "marshal", GoType: t, Err: err}
   106  			}
   107  			return nil
   108  		}
   109  	case jsonMarshalerV1Type:
   110  		fncs.nonDefault = true
   111  		fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
   112  			marshaler := va.addrWhen(needAddr).Interface().(MarshalerV1)
   113  			val, err := marshaler.MarshalJSON()
   114  			if err != nil {
   115  				err = wrapSkipFunc(err, "marshal method")
   116  				// TODO: Avoid wrapping semantic errors.
   117  				return &SemanticError{action: "marshal", GoType: t, Err: err}
   118  			}
   119  			if err := enc.WriteValue(val); err != nil {
   120  				// TODO: Avoid wrapping semantic or I/O errors.
   121  				return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err}
   122  			}
   123  			return nil
   124  		}
   125  	case textMarshalerType:
   126  		fncs.nonDefault = true
   127  		fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
   128  			marshaler := va.addrWhen(needAddr).Interface().(encoding.TextMarshaler)
   129  			s, err := marshaler.MarshalText()
   130  			if err != nil {
   131  				err = wrapSkipFunc(err, "marshal method")
   132  				// TODO: Avoid wrapping semantic errors.
   133  				return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err}
   134  			}
   135  			val := enc.UnusedBuffer()
   136  			val, err = appendString(val, string(s), true, nil)
   137  			if err != nil {
   138  				return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err}
   139  			}
   140  			if err := enc.WriteValue(val); err != nil {
   141  				// TODO: Avoid wrapping syntactic or I/O errors.
   142  				return &SemanticError{action: "marshal", JSONKind: '"', GoType: t, Err: err}
   143  			}
   144  			return nil
   145  		}
   146  	}
   147  
   148  	// Handle custom unmarshaler.
   149  	switch which, needAddr := implementsWhich(t, jsonUnmarshalerV2Type, jsonUnmarshalerV1Type, textUnmarshalerType); which {
   150  	case jsonUnmarshalerV2Type:
   151  		fncs.nonDefault = true
   152  		fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
   153  			prevDepth, prevLength := dec.tokens.depthLength()
   154  			err := va.addrWhen(needAddr).Interface().(UnmarshalerV2).UnmarshalNextJSON(uo, dec)
   155  			currDepth, currLength := dec.tokens.depthLength()
   156  			if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil {
   157  				err = errors.New("must read exactly one JSON value")
   158  			}
   159  			if err != nil {
   160  				err = wrapSkipFunc(err, "unmarshal method")
   161  				// TODO: Avoid wrapping semantic, syntactic, or I/O errors.
   162  				return &SemanticError{action: "unmarshal", GoType: t, Err: err}
   163  			}
   164  			return nil
   165  		}
   166  	case jsonUnmarshalerV1Type:
   167  		fncs.nonDefault = true
   168  		fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
   169  			val, err := dec.ReadValue()
   170  			if err != nil {
   171  				return err // must be a syntactic or I/O error
   172  			}
   173  			unmarshaler := va.addrWhen(needAddr).Interface().(UnmarshalerV1)
   174  			if err := unmarshaler.UnmarshalJSON(val); err != nil {
   175  				err = wrapSkipFunc(err, "unmarshal method")
   176  				// TODO: Avoid wrapping semantic, syntactic, or I/O errors.
   177  				return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err}
   178  			}
   179  			return nil
   180  		}
   181  	case textUnmarshalerType:
   182  		fncs.nonDefault = true
   183  		fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error {
   184  			var flags valueFlags
   185  			val, err := dec.readValue(&flags)
   186  			if err != nil {
   187  				return err // must be a syntactic or I/O error
   188  			}
   189  			if val.Kind() != '"' {
   190  				err = errors.New("JSON value must be string type")
   191  				return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err}
   192  			}
   193  			s := unescapeStringMayCopy(val, flags.isVerbatim())
   194  			unmarshaler := va.addrWhen(needAddr).Interface().(encoding.TextUnmarshaler)
   195  			if err := unmarshaler.UnmarshalText(s); err != nil {
   196  				err = wrapSkipFunc(err, "unmarshal method")
   197  				// TODO: Avoid wrapping semantic, syntactic, or I/O errors.
   198  				return &SemanticError{action: "unmarshal", JSONKind: val.Kind(), GoType: t, Err: err}
   199  			}
   200  			return nil
   201  		}
   202  	}
   203  
   204  	return fncs
   205  }
   206  
   207  // implementsWhich is like t.Implements(ifaceType) for a list of interfaces,
   208  // but checks whether either t or reflect.PointerTo(t) implements the interface.
   209  // It returns the first interface type that matches and whether a value of t
   210  // needs to be addressed first before it implements the interface.
   211  func implementsWhich(t reflect.Type, ifaceTypes ...reflect.Type) (which reflect.Type, needAddr bool) {
   212  	for _, ifaceType := range ifaceTypes {
   213  		switch {
   214  		case t.Implements(ifaceType):
   215  			return ifaceType, false
   216  		case reflect.PointerTo(t).Implements(ifaceType):
   217  			return ifaceType, true
   218  		}
   219  	}
   220  	return nil, false
   221  }
   222  
   223  // addrWhen returns va.Addr if addr is specified, otherwise it returns itself.
   224  func (va addressableValue) addrWhen(addr bool) reflect.Value {
   225  	if addr {
   226  		return va.Addr()
   227  	}
   228  	return va.Value
   229  }