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 }