github.com/anthropics/anthropic-sdk-go@v1.70.1/internal/apijson/decoder.go (about) 1 // The deserialization algorithm from apijson may be subject to improvements 2 // between minor versions, particularly with respect to calling [json.Unmarshal] 3 // into param unions. 4 5 package apijson 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "reflect" 11 "strconv" 12 "sync" 13 "time" 14 "unsafe" 15 16 "github.com/anthropics/anthropic-sdk-go/packages/param" 17 18 "github.com/tidwall/gjson" 19 ) 20 21 // decoders is a synchronized map with roughly the following type: 22 // map[reflect.Type]decoderFunc 23 var decoders sync.Map 24 25 // Unmarshal is similar to [encoding/json.Unmarshal] and parses the JSON-encoded 26 // data and stores it in the given pointer. 27 func Unmarshal(raw []byte, to any) error { 28 d := &decoderBuilder{dateFormat: time.RFC3339} 29 return d.unmarshal(raw, to) 30 } 31 32 // UnmarshalRoot is like Unmarshal, but doesn't try to call MarshalJSON on the 33 // root element. Useful if a struct's UnmarshalJSON is overrode to use the 34 // behavior of this encoder versus the standard library. 35 func UnmarshalRoot(raw []byte, to any) error { 36 d := &decoderBuilder{dateFormat: time.RFC3339, root: true} 37 return d.unmarshal(raw, to) 38 } 39 40 // decoderBuilder contains the 'compile-time' state of the decoder. 41 type decoderBuilder struct { 42 // Whether or not this is the first element and called by [UnmarshalRoot], see 43 // the documentation there to see why this is necessary. 44 root bool 45 // The dateFormat (a format string for [time.Format]) which is chosen by the 46 // last struct tag that was seen. 47 dateFormat string 48 } 49 50 // decoderState contains the 'run-time' state of the decoder. 51 type decoderState struct { 52 strict bool 53 exactness exactness 54 validator *validationEntry 55 } 56 57 type decoderFunc func(node gjson.Result, value reflect.Value, state *decoderState) error 58 59 type decoderField struct { 60 tag parsedStructTag 61 fn decoderFunc 62 idx []int 63 goname string 64 } 65 66 type decoderEntry struct { 67 typ reflect.Type 68 dateFormat string 69 root bool 70 } 71 72 func (d *decoderBuilder) unmarshal(raw []byte, to any) error { 73 value := reflect.ValueOf(to).Elem() 74 result := gjson.ParseBytes(raw) 75 if !value.IsValid() { 76 return fmt.Errorf("apijson: cannot unmarshal into invalid value") 77 } 78 return d.typeDecoder(value.Type())(result, value, &decoderState{}) 79 } 80 81 // unmarshalWithExactness is used for internal testing purposes. 82 func (d *decoderBuilder) unmarshalWithExactness(raw []byte, to any) (exactness, error) { 83 value := reflect.ValueOf(to).Elem() 84 result := gjson.ParseBytes(raw) 85 if !value.IsValid() { 86 return exactness{}, fmt.Errorf("apijson: cannot marshal into invalid value") 87 } 88 var state decoderState 89 err := d.typeDecoder(value.Type())(result, value, &state) 90 return state.exactness, err 91 } 92 93 func (d *decoderBuilder) typeDecoder(t reflect.Type) decoderFunc { 94 entry := decoderEntry{ 95 typ: t, 96 dateFormat: d.dateFormat, 97 root: d.root, 98 } 99 100 if fi, ok := decoders.Load(entry); ok { 101 return fi.(decoderFunc) 102 } 103 104 // To deal with recursive types, populate the map with an 105 // indirect func before we build it. This type waits on the 106 // real func (f) to be ready and then calls it. This indirect 107 // func is only used for recursive types. 108 var ( 109 wg sync.WaitGroup 110 f decoderFunc 111 ) 112 wg.Add(1) 113 fi, loaded := decoders.LoadOrStore(entry, decoderFunc(func(node gjson.Result, v reflect.Value, state *decoderState) error { 114 wg.Wait() 115 return f(node, v, state) 116 })) 117 if loaded { 118 return fi.(decoderFunc) 119 } 120 121 // Compute the real decoder and replace the indirect func with it. 122 f = d.newTypeDecoder(t) 123 wg.Done() 124 decoders.Store(entry, f) 125 return f 126 } 127 128 // validatedTypeDecoder wraps the type decoder with a validator. This is helpful 129 // for ensuring that enum fields are correct. 130 func (d *decoderBuilder) validatedTypeDecoder(t reflect.Type, entry *validationEntry) decoderFunc { 131 dec := d.typeDecoder(t) 132 if entry == nil { 133 return dec 134 } 135 136 // Thread the current validation entry through the decoder, 137 // but clean up in time for the next field. 138 return func(node gjson.Result, v reflect.Value, state *decoderState) error { 139 state.validator = entry 140 err := dec(node, v, state) 141 state.validator = nil 142 return err 143 } 144 } 145 146 func indirectUnmarshalerDecoder(n gjson.Result, v reflect.Value, state *decoderState) error { 147 return v.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw)) 148 } 149 150 func customUnmarshalerDecoder(n gjson.Result, v reflect.Value, state *decoderState) error { 151 if v.Kind() == reflect.Pointer && v.CanSet() { 152 v.Set(reflect.New(v.Type().Elem())) 153 } 154 if u, ok := v.Interface().(CustomUnmarshaler); ok { 155 return u.UnmarshalAPIJSON([]byte(n.Raw)) 156 } 157 return v.Addr().Interface().(CustomUnmarshaler).UnmarshalAPIJSON([]byte(n.Raw)) 158 } 159 160 func unmarshalerDecoder(n gjson.Result, v reflect.Value, state *decoderState) error { 161 if v.Kind() == reflect.Pointer && v.CanSet() { 162 v.Set(reflect.New(v.Type().Elem())) 163 } 164 return v.Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw)) 165 } 166 167 func (d *decoderBuilder) newTypeDecoder(t reflect.Type) decoderFunc { 168 // Check for custom decoders first 169 if customDecoder, ok := customDecoderRegistry[t]; ok { 170 // Create the default decoder for this type (without the custom decoder) 171 defaultDecoder := d.newDefaultTypeDecoder(t) 172 return func(node gjson.Result, value reflect.Value, state *decoderState) error { 173 // Provide a wrapper that removes the state parameter for the custom decoder 174 defaultWrapper := func(node gjson.Result, value reflect.Value) error { 175 return defaultDecoder(node, value, state) 176 } 177 return customDecoder(node, value, defaultWrapper) 178 } 179 } 180 181 return d.newDefaultTypeDecoder(t) 182 } 183 184 func (d *decoderBuilder) newDefaultTypeDecoder(t reflect.Type) decoderFunc { 185 if t.ConvertibleTo(reflect.TypeOf(time.Time{})) { 186 return d.newTimeTypeDecoder(t) 187 } 188 189 if t.Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) { 190 return d.newOptTypeDecoder(t) 191 } 192 193 if !d.root && implementsCustomUnmarshaler(t) { 194 return customUnmarshalerDecoder 195 } 196 197 // apijson-native types are decoded directly; see [isApijsonNative]. 198 if !d.root && !isApijsonNative(t) && t.Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()) { 199 return unmarshalerDecoder 200 } 201 if !d.root && !isApijsonNative(t) && reflect.PointerTo(t).Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()) { 202 if _, ok := unionVariants[t]; !ok { 203 return indirectUnmarshalerDecoder 204 } 205 } 206 d.root = false 207 208 if _, ok := unionRegistry[t]; ok { 209 if isStructUnion(t) { 210 return d.newStructUnionDecoder(t) 211 } 212 return d.newUnionDecoder(t) 213 } 214 215 switch t.Kind() { 216 case reflect.Pointer: 217 inner := t.Elem() 218 innerDecoder := d.typeDecoder(inner) 219 220 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 221 if !v.IsValid() { 222 return fmt.Errorf("apijson: unexpected invalid reflection value %+#v", v) 223 } 224 225 newValue := reflect.New(inner).Elem() 226 err := innerDecoder(n, newValue, state) 227 if err != nil { 228 return err 229 } 230 231 v.Set(newValue.Addr()) 232 return nil 233 } 234 case reflect.Struct: 235 if isStructUnion(t) { 236 return d.newStructUnionDecoder(t) 237 } 238 return d.newStructTypeDecoder(t) 239 case reflect.Array: 240 fallthrough 241 case reflect.Slice: 242 return d.newArrayTypeDecoder(t) 243 case reflect.Map: 244 return d.newMapDecoder(t) 245 case reflect.Interface: 246 return func(node gjson.Result, value reflect.Value, state *decoderState) error { 247 if !value.IsValid() { 248 return fmt.Errorf("apijson: unexpected invalid value %+#v", value) 249 } 250 if node.Value() != nil && value.CanSet() { 251 value.Set(reflect.ValueOf(node.Value())) 252 } 253 return nil 254 } 255 default: 256 return d.newPrimitiveTypeDecoder(t) 257 } 258 } 259 260 func (d *decoderBuilder) newMapDecoder(t reflect.Type) decoderFunc { 261 keyType := t.Key() 262 itemType := t.Elem() 263 itemDecoder := d.typeDecoder(itemType) 264 265 return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) { 266 mapValue := reflect.MakeMapWithSize(t, len(node.Map())) 267 268 node.ForEach(func(key, value gjson.Result) bool { 269 // It's fine for us to just use `ValueOf` here because the key types will 270 // always be primitive types so we don't need to decode it using the standard pattern 271 keyValue := reflect.ValueOf(key.Value()) 272 if !keyValue.IsValid() { 273 if err == nil { 274 err = fmt.Errorf("apijson: received invalid key type %v", keyValue.String()) 275 } 276 return false 277 } 278 if keyValue.Type() != keyType { 279 if err == nil { 280 err = fmt.Errorf("apijson: expected key type %v but got %v", keyType, keyValue.Type()) 281 } 282 return false 283 } 284 285 itemValue := reflect.New(itemType).Elem() 286 itemerr := itemDecoder(value, itemValue, state) 287 if itemerr != nil { 288 if err == nil { 289 err = itemerr 290 } 291 return false 292 } 293 294 mapValue.SetMapIndex(keyValue, itemValue) 295 return true 296 }) 297 298 if err != nil { 299 return err 300 } 301 value.Set(mapValue) 302 return nil 303 } 304 } 305 306 func (d *decoderBuilder) newArrayTypeDecoder(t reflect.Type) decoderFunc { 307 itemDecoder := d.typeDecoder(t.Elem()) 308 309 return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) { 310 if !node.IsArray() { 311 return fmt.Errorf("apijson: could not deserialize to an array") 312 } 313 314 arrayNode := node.Array() 315 316 arrayValue := reflect.MakeSlice(reflect.SliceOf(t.Elem()), len(arrayNode), len(arrayNode)) 317 for i, itemNode := range arrayNode { 318 err = itemDecoder(itemNode, arrayValue.Index(i), state) 319 if err != nil { 320 return err 321 } 322 } 323 324 value.Set(arrayValue) 325 return nil 326 } 327 } 328 329 func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc { 330 // map of json field name to struct field decoders 331 decoderFields := map[string]decoderField{} 332 anonymousDecoders := []decoderField{} 333 extraDecoder := (*decoderField)(nil) 334 var inlineDecoders []decoderField 335 336 // Missing api:"required" fields lower a param variant's rank. 337 isParam := isParamStruct(t) 338 requiredCount := 0 339 340 validationEntries := validationRegistry[t] 341 342 for i := 0; i < t.NumField(); i++ { 343 idx := []int{i} 344 field := t.FieldByIndex(idx) 345 if !field.IsExported() { 346 continue 347 } 348 349 var validator *validationEntry 350 for _, entry := range validationEntries { 351 if entry.field.Offset == field.Offset { 352 validator = &entry 353 break 354 } 355 } 356 357 // If this is an embedded struct, traverse one level deeper to extract 358 // the fields and get their encoders as well. 359 if field.Anonymous { 360 anonymousDecoders = append(anonymousDecoders, decoderField{ 361 fn: d.typeDecoder(field.Type), 362 idx: idx[:], 363 }) 364 continue 365 } 366 // If json tag is not present, then we skip, which is intentionally 367 // different behavior from the stdlib. 368 ptag, ok := parseJSONStructTag(field) 369 if !ok { 370 continue 371 } 372 // We only want to support unexported fields if they're tagged with 373 // `extras` because that field shouldn't be part of the public API. 374 if ptag.extras { 375 extraDecoder = &decoderField{ptag, d.typeDecoder(field.Type.Elem()), idx, field.Name} 376 continue 377 } 378 if ptag.inline { 379 df := decoderField{ptag, d.typeDecoder(field.Type), idx, field.Name} 380 inlineDecoders = append(inlineDecoders, df) 381 continue 382 } 383 if ptag.metadata { 384 continue 385 } 386 387 oldFormat := d.dateFormat 388 dateFormat, ok := parseFormatStructTag(field) 389 if ok { 390 switch dateFormat { 391 case "date-time": 392 d.dateFormat = time.RFC3339 393 case "date": 394 d.dateFormat = "2006-01-02" 395 } 396 } 397 398 fn := d.validatedTypeDecoder(field.Type, validator) 399 if def, ok := ptag.defaultValue.(string); ok && field.Type.Kind() == reflect.String { 400 fn = constantFieldDecoder(fn, def) 401 } 402 decoderFields[ptag.name] = decoderField{ptag, fn, idx, field.Name} 403 if isParam && ptag.required { 404 requiredCount++ 405 } 406 407 d.dateFormat = oldFormat 408 } 409 410 return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) { 411 if field := value.FieldByName("JSON"); field.IsValid() { 412 if raw := field.FieldByName("raw"); raw.IsValid() { 413 setUnexportedField(raw, node.Raw) 414 } 415 } 416 417 for _, decoder := range anonymousDecoders { 418 // ignore errors 419 _ = decoder.fn(node, value.FieldByIndex(decoder.idx), state) 420 } 421 422 for _, inlineDecoder := range inlineDecoders { 423 var meta Field 424 dest := value.FieldByIndex(inlineDecoder.idx) 425 isValid := false 426 if dest.IsValid() && node.Type != gjson.Null { 427 inlineState := decoderState{exactness: state.exactness, strict: true} 428 err = inlineDecoder.fn(node, dest, &inlineState) 429 if err == nil { 430 isValid = true 431 } 432 } 433 434 if node.Type == gjson.Null { 435 meta = Field{ 436 raw: node.Raw, 437 status: null, 438 } 439 } else if !isValid { 440 // If an inline decoder fails, unset the field and move on. 441 if dest.IsValid() { 442 dest.SetZero() 443 } 444 continue 445 } else if isValid { 446 meta = Field{ 447 raw: node.Raw, 448 status: valid, 449 } 450 } 451 setMetadataSubField(value, inlineDecoder.idx, inlineDecoder.goname, meta) 452 } 453 454 typedExtraType := reflect.Type(nil) 455 typedExtraFields := reflect.Value{} 456 if extraDecoder != nil { 457 typedExtraType = value.FieldByIndex(extraDecoder.idx).Type() 458 typedExtraFields = reflect.MakeMap(typedExtraType) 459 } 460 untypedExtraFields := map[string]Field{} 461 seenRequired := 0 462 463 for fieldName, itemNode := range node.Map() { 464 df, explicit := decoderFields[fieldName] 465 var ( 466 dest reflect.Value 467 fn decoderFunc 468 meta Field 469 ) 470 if explicit { 471 fn = df.fn 472 dest = value.FieldByIndex(df.idx) 473 } 474 if !explicit && extraDecoder != nil { 475 dest = reflect.New(typedExtraType.Elem()).Elem() 476 fn = extraDecoder.fn 477 } 478 479 // Handle null [param.Opt] 480 if itemNode.Type == gjson.Null && dest.IsValid() && dest.Type().Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) { 481 _ = dest.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(itemNode.Raw)) 482 if explicit && df.tag.required { 483 seenRequired++ 484 } 485 continue 486 } 487 488 isValid := false 489 if dest.IsValid() && itemNode.Type != gjson.Null { 490 err = fn(itemNode, dest, state) 491 if err == nil { 492 isValid = true 493 } else { 494 state.exactness.noteFieldError() 495 } 496 } 497 if explicit && df.tag.required && isValid { 498 seenRequired++ 499 } 500 501 if itemNode.Type == gjson.Null { 502 meta = Field{ 503 raw: itemNode.Raw, 504 status: null, 505 } 506 } else if !isValid { 507 meta = Field{ 508 raw: itemNode.Raw, 509 status: invalid, 510 } 511 } else if isValid { 512 meta = Field{ 513 raw: itemNode.Raw, 514 status: valid, 515 } 516 } 517 518 if explicit { 519 setMetadataSubField(value, df.idx, df.goname, meta) 520 } 521 if !explicit { 522 untypedExtraFields[fieldName] = meta 523 } 524 if !explicit && extraDecoder != nil { 525 typedExtraFields.SetMapIndex(reflect.ValueOf(fieldName), dest) 526 } 527 } 528 529 if extraDecoder != nil && typedExtraFields.Len() > 0 { 530 value.FieldByIndex(extraDecoder.idx).Set(typedExtraFields) 531 } 532 533 if seenRequired < requiredCount { 534 state.exactness.noteRequiredMissing(requiredCount - seenRequired) 535 } 536 537 if len(untypedExtraFields) > 0 { 538 state.exactness.noteExtras() 539 setMetadataExtraFields(value, []int{-1}, "ExtraFields", untypedExtraFields) 540 } 541 return nil 542 } 543 } 544 545 func (d *decoderBuilder) newPrimitiveTypeDecoder(t reflect.Type) decoderFunc { 546 switch t.Kind() { 547 case reflect.String: 548 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 549 v.SetString(n.String()) 550 if guardStrict(state, n.Type != gjson.String) { 551 return fmt.Errorf("apijson: failed to parse string strictly") 552 } 553 // Everything that is not an object can be loosely stringified. 554 if n.Type == gjson.JSON { 555 return fmt.Errorf("apijson: failed to parse string") 556 } 557 558 state.validateString(v) 559 560 if guardUnknown(state, v) { 561 return fmt.Errorf("apijson: failed string enum validation") 562 } 563 return nil 564 } 565 case reflect.Bool: 566 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 567 v.SetBool(n.Bool()) 568 if guardStrict(state, n.Type != gjson.True && n.Type != gjson.False) { 569 return fmt.Errorf("apijson: failed to parse bool strictly") 570 } 571 // Numbers and strings that are either 'true' or 'false' can be loosely 572 // deserialized as bool. 573 if n.Type == gjson.String && (n.Raw != "true" && n.Raw != "false") || n.Type == gjson.JSON { 574 return fmt.Errorf("apijson: failed to parse bool") 575 } 576 577 state.validateBool(v) 578 579 if guardUnknown(state, v) { 580 return fmt.Errorf("apijson: failed bool enum validation") 581 } 582 return nil 583 } 584 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 585 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 586 v.SetInt(n.Int()) 587 if guardStrict(state, n.Type != gjson.Number || n.Num != float64(int(n.Num))) { 588 return fmt.Errorf("apijson: failed to parse int strictly") 589 } 590 // Numbers, booleans, and strings that maybe look like numbers can be 591 // loosely deserialized as numbers. 592 if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) { 593 return fmt.Errorf("apijson: failed to parse int") 594 } 595 596 state.validateInt(v) 597 598 if guardUnknown(state, v) { 599 return fmt.Errorf("apijson: failed int enum validation") 600 } 601 return nil 602 } 603 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 604 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 605 v.SetUint(n.Uint()) 606 if guardStrict(state, n.Type != gjson.Number || n.Num != float64(int(n.Num)) || n.Num < 0) { 607 return fmt.Errorf("apijson: failed to parse uint strictly") 608 } 609 // Numbers, booleans, and strings that maybe look like numbers can be 610 // loosely deserialized as uint. 611 if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) { 612 return fmt.Errorf("apijson: failed to parse uint") 613 } 614 if guardUnknown(state, v) { 615 return fmt.Errorf("apijson: failed uint enum validation") 616 } 617 return nil 618 } 619 case reflect.Float32, reflect.Float64: 620 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 621 v.SetFloat(n.Float()) 622 if guardStrict(state, n.Type != gjson.Number) { 623 return fmt.Errorf("apijson: failed to parse float strictly") 624 } 625 // Numbers, booleans, and strings that maybe look like numbers can be 626 // loosely deserialized as floats. 627 if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) { 628 return fmt.Errorf("apijson: failed to parse float") 629 } 630 if guardUnknown(state, v) { 631 return fmt.Errorf("apijson: failed float enum validation") 632 } 633 return nil 634 } 635 default: 636 return func(node gjson.Result, v reflect.Value, state *decoderState) error { 637 return fmt.Errorf("unknown type received at primitive decoder: %s", t.String()) 638 } 639 } 640 } 641 642 func (d *decoderBuilder) newOptTypeDecoder(t reflect.Type) decoderFunc { 643 for t.Kind() == reflect.Pointer { 644 t = t.Elem() 645 } 646 valueField, _ := t.FieldByName("Value") 647 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 648 state.validateOptKind(n, valueField.Type) 649 return v.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw)) 650 } 651 } 652 653 func (d *decoderBuilder) newTimeTypeDecoder(t reflect.Type) decoderFunc { 654 format := d.dateFormat 655 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 656 parsed, err := time.Parse(format, n.Str) 657 if err == nil { 658 v.Set(reflect.ValueOf(parsed).Convert(t)) 659 return nil 660 } 661 662 if guardStrict(state, true) { 663 return err 664 } 665 666 layouts := []string{ 667 "2006-01-02", 668 "2006-01-02T15:04:05Z07:00", 669 "2006-01-02T15:04:05Z0700", 670 "2006-01-02T15:04:05", 671 "2006-01-02 15:04:05Z07:00", 672 "2006-01-02 15:04:05Z0700", 673 "2006-01-02 15:04:05", 674 } 675 676 for _, layout := range layouts { 677 parsed, err := time.Parse(layout, n.Str) 678 if err == nil { 679 v.Set(reflect.ValueOf(parsed).Convert(t)) 680 return nil 681 } 682 } 683 684 return fmt.Errorf("unable to leniently parse date-time string: %s", n.Str) 685 } 686 } 687 688 func setUnexportedField(field reflect.Value, value any) { 689 reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Set(reflect.ValueOf(value)) 690 } 691 692 func guardStrict(state *decoderState, cond bool) bool { 693 if !cond { 694 return false 695 } 696 697 if state.strict { 698 return true 699 } 700 701 state.exactness.noteCoercion() 702 return false 703 } 704 705 func canParseAsNumber(str string) bool { 706 _, err := strconv.ParseFloat(str, 64) 707 return err == nil 708 } 709 710 func guardUnknown(state *decoderState, v reflect.Value) bool { 711 if have, ok := v.Interface().(interface{ IsKnown() bool }); ok && !have.IsKnown() { 712 state.exactness.noteCoercion() 713 } 714 return false 715 } 716 717 // To feed union variant selection, record whether a constant field 718 // matched its default. 719 func constantFieldDecoder(inner decoderFunc, def string) decoderFunc { 720 return func(n gjson.Result, v reflect.Value, state *decoderState) error { 721 if err := inner(n, v, state); err != nil { 722 return err 723 } 724 if v.String() == def { 725 state.exactness.noteConstMatch() 726 } else { 727 state.exactness.noteConstMismatch() 728 } 729 return nil 730 } 731 }