github.com/shuguocloud/go-zero@v1.3.0/core/mapping/unmarshaler.go (about) 1 package mapping 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "reflect" 8 "strings" 9 "sync" 10 "time" 11 12 "github.com/shuguocloud/go-zero/core/jsonx" 13 "github.com/shuguocloud/go-zero/core/lang" 14 "github.com/shuguocloud/go-zero/core/stringx" 15 ) 16 17 const ( 18 defaultKeyName = "key" 19 delimiter = '.' 20 ) 21 22 var ( 23 errTypeMismatch = errors.New("type mismatch") 24 errValueNotSettable = errors.New("value is not settable") 25 errValueNotStruct = errors.New("value type is not struct") 26 keyUnmarshaler = NewUnmarshaler(defaultKeyName) 27 durationType = reflect.TypeOf(time.Duration(0)) 28 cacheKeys map[string][]string 29 cacheKeysLock sync.Mutex 30 defaultCache map[string]interface{} 31 defaultCacheLock sync.Mutex 32 emptyMap = map[string]interface{}{} 33 emptyValue = reflect.ValueOf(lang.Placeholder) 34 ) 35 36 type ( 37 // Unmarshaler is used to unmarshal with given tag key. 38 Unmarshaler struct { 39 key string 40 opts unmarshalOptions 41 } 42 43 // UnmarshalOption defines the method to customize a Unmarshaler. 44 UnmarshalOption func(*unmarshalOptions) 45 46 unmarshalOptions struct { 47 fromString bool 48 canonicalKey func(key string) string 49 } 50 ) 51 52 func init() { 53 cacheKeys = make(map[string][]string) 54 defaultCache = make(map[string]interface{}) 55 } 56 57 // NewUnmarshaler returns a Unmarshaler. 58 func NewUnmarshaler(key string, opts ...UnmarshalOption) *Unmarshaler { 59 unmarshaler := Unmarshaler{ 60 key: key, 61 } 62 63 for _, opt := range opts { 64 opt(&unmarshaler.opts) 65 } 66 67 return &unmarshaler 68 } 69 70 // UnmarshalKey unmarshals m into v with tag key. 71 func UnmarshalKey(m map[string]interface{}, v interface{}) error { 72 return keyUnmarshaler.Unmarshal(m, v) 73 } 74 75 // Unmarshal unmarshals m into v. 76 func (u *Unmarshaler) Unmarshal(m map[string]interface{}, v interface{}) error { 77 return u.UnmarshalValuer(MapValuer(m), v) 78 } 79 80 // UnmarshalValuer unmarshals m into v. 81 func (u *Unmarshaler) UnmarshalValuer(m Valuer, v interface{}) error { 82 return u.unmarshalWithFullName(m, v, "") 83 } 84 85 func (u *Unmarshaler) unmarshalWithFullName(m Valuer, v interface{}, fullName string) error { 86 rv := reflect.ValueOf(v) 87 if err := ValidatePtr(&rv); err != nil { 88 return err 89 } 90 91 rte := reflect.TypeOf(v).Elem() 92 if rte.Kind() != reflect.Struct { 93 return errValueNotStruct 94 } 95 96 rve := rv.Elem() 97 numFields := rte.NumField() 98 for i := 0; i < numFields; i++ { 99 field := rte.Field(i) 100 if usingDifferentKeys(u.key, field) { 101 continue 102 } 103 104 if err := u.processField(field, rve.Field(i), m, fullName); err != nil { 105 return err 106 } 107 } 108 109 return nil 110 } 111 112 func (u *Unmarshaler) processAnonymousField(field reflect.StructField, value reflect.Value, 113 m Valuer, fullName string) error { 114 key, options, err := u.parseOptionsWithContext(field, m, fullName) 115 if err != nil { 116 return err 117 } 118 119 if _, hasValue := getValue(m, key); hasValue { 120 return fmt.Errorf("fields of %s can't be wrapped inside, because it's anonymous", key) 121 } 122 123 if options.optional() { 124 return u.processAnonymousFieldOptional(field, value, key, m, fullName) 125 } 126 127 return u.processAnonymousFieldRequired(field, value, m, fullName) 128 } 129 130 func (u *Unmarshaler) processAnonymousFieldOptional(field reflect.StructField, value reflect.Value, 131 key string, m Valuer, fullName string) error { 132 var filled bool 133 var required int 134 var requiredFilled int 135 var indirectValue reflect.Value 136 fieldType := Deref(field.Type) 137 138 for i := 0; i < fieldType.NumField(); i++ { 139 subField := fieldType.Field(i) 140 fieldKey, fieldOpts, err := u.parseOptionsWithContext(subField, m, fullName) 141 if err != nil { 142 return err 143 } 144 145 _, hasValue := getValue(m, fieldKey) 146 if hasValue { 147 if !filled { 148 filled = true 149 maybeNewValue(field, value) 150 indirectValue = reflect.Indirect(value) 151 152 } 153 if err = u.processField(subField, indirectValue.Field(i), m, fullName); err != nil { 154 return err 155 } 156 } 157 if !fieldOpts.optional() { 158 required++ 159 if hasValue { 160 requiredFilled++ 161 } 162 } 163 } 164 165 if filled && required != requiredFilled { 166 return fmt.Errorf("%s is not fully set", key) 167 } 168 169 return nil 170 } 171 172 func (u *Unmarshaler) processAnonymousFieldRequired(field reflect.StructField, value reflect.Value, 173 m Valuer, fullName string) error { 174 maybeNewValue(field, value) 175 fieldType := Deref(field.Type) 176 indirectValue := reflect.Indirect(value) 177 178 for i := 0; i < fieldType.NumField(); i++ { 179 if err := u.processField(fieldType.Field(i), indirectValue.Field(i), m, fullName); err != nil { 180 return err 181 } 182 } 183 184 return nil 185 } 186 187 func (u *Unmarshaler) processField(field reflect.StructField, value reflect.Value, m Valuer, 188 fullName string) error { 189 if usingDifferentKeys(u.key, field) { 190 return nil 191 } 192 193 if field.Anonymous { 194 return u.processAnonymousField(field, value, m, fullName) 195 } 196 197 return u.processNamedField(field, value, m, fullName) 198 } 199 200 func (u *Unmarshaler) processFieldNotFromString(field reflect.StructField, value reflect.Value, 201 mapValue interface{}, opts *fieldOptionsWithContext, fullName string) error { 202 fieldType := field.Type 203 derefedFieldType := Deref(fieldType) 204 typeKind := derefedFieldType.Kind() 205 valueKind := reflect.TypeOf(mapValue).Kind() 206 207 switch { 208 case valueKind == reflect.Map && typeKind == reflect.Struct: 209 return u.processFieldStruct(field, value, mapValue, fullName) 210 case valueKind == reflect.Map && typeKind == reflect.Map: 211 return u.fillMap(field, value, mapValue) 212 case valueKind == reflect.String && typeKind == reflect.Slice: 213 return u.fillSliceFromString(fieldType, value, mapValue) 214 case valueKind == reflect.String && derefedFieldType == durationType: 215 return fillDurationValue(fieldType.Kind(), value, mapValue.(string)) 216 default: 217 return u.processFieldPrimitive(field, value, mapValue, opts, fullName) 218 } 219 } 220 221 func (u *Unmarshaler) processFieldPrimitive(field reflect.StructField, value reflect.Value, 222 mapValue interface{}, opts *fieldOptionsWithContext, fullName string) error { 223 fieldType := field.Type 224 typeKind := Deref(fieldType).Kind() 225 valueKind := reflect.TypeOf(mapValue).Kind() 226 227 switch { 228 case typeKind == reflect.Slice && valueKind == reflect.Slice: 229 return u.fillSlice(fieldType, value, mapValue) 230 case typeKind == reflect.Map && valueKind == reflect.Map: 231 return u.fillMap(field, value, mapValue) 232 default: 233 switch v := mapValue.(type) { 234 case json.Number: 235 return u.processFieldPrimitiveWithJSONNumber(field, value, v, opts, fullName) 236 default: 237 if typeKind == valueKind { 238 if err := validateValueInOptions(opts.options(), mapValue); err != nil { 239 return err 240 } 241 242 return fillWithSameType(field, value, mapValue, opts) 243 } 244 } 245 } 246 247 return newTypeMismatchError(fullName) 248 } 249 250 func (u *Unmarshaler) processFieldPrimitiveWithJSONNumber(field reflect.StructField, value reflect.Value, 251 v json.Number, opts *fieldOptionsWithContext, fullName string) error { 252 fieldType := field.Type 253 fieldKind := fieldType.Kind() 254 typeKind := Deref(fieldType).Kind() 255 256 if err := validateJsonNumberRange(v, opts); err != nil { 257 return err 258 } 259 260 if fieldKind == reflect.Ptr { 261 value = value.Elem() 262 } 263 264 switch typeKind { 265 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 266 iValue, err := v.Int64() 267 if err != nil { 268 return err 269 } 270 271 value.SetInt(iValue) 272 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 273 iValue, err := v.Int64() 274 if err != nil { 275 return err 276 } 277 278 value.SetUint(uint64(iValue)) 279 case reflect.Float32, reflect.Float64: 280 fValue, err := v.Float64() 281 if err != nil { 282 return err 283 } 284 285 value.SetFloat(fValue) 286 default: 287 return newTypeMismatchError(fullName) 288 } 289 290 return nil 291 } 292 293 func (u *Unmarshaler) processFieldStruct(field reflect.StructField, value reflect.Value, 294 mapValue interface{}, fullName string) error { 295 convertedValue, ok := mapValue.(map[string]interface{}) 296 if !ok { 297 valueKind := reflect.TypeOf(mapValue).Kind() 298 return fmt.Errorf("error: field: %s, expect map[string]interface{}, actual %v", fullName, valueKind) 299 } 300 301 return u.processFieldStructWithMap(field, value, MapValuer(convertedValue), fullName) 302 } 303 304 func (u *Unmarshaler) processFieldStructWithMap(field reflect.StructField, value reflect.Value, 305 m Valuer, fullName string) error { 306 if field.Type.Kind() == reflect.Ptr { 307 baseType := Deref(field.Type) 308 target := reflect.New(baseType).Elem() 309 if err := u.unmarshalWithFullName(m, target.Addr().Interface(), fullName); err != nil { 310 return err 311 } 312 313 value.Set(target.Addr()) 314 } else if err := u.unmarshalWithFullName(m, value.Addr().Interface(), fullName); err != nil { 315 return err 316 } 317 318 return nil 319 } 320 321 func (u *Unmarshaler) processNamedField(field reflect.StructField, value reflect.Value, 322 m Valuer, fullName string) error { 323 key, opts, err := u.parseOptionsWithContext(field, m, fullName) 324 if err != nil { 325 return err 326 } 327 328 fullName = join(fullName, key) 329 canonicalKey := key 330 if u.opts.canonicalKey != nil { 331 canonicalKey = u.opts.canonicalKey(key) 332 } 333 mapValue, hasValue := getValue(m, canonicalKey) 334 if hasValue { 335 return u.processNamedFieldWithValue(field, value, mapValue, key, opts, fullName) 336 } 337 338 return u.processNamedFieldWithoutValue(field, value, opts, fullName) 339 } 340 341 func (u *Unmarshaler) processNamedFieldWithValue(field reflect.StructField, value reflect.Value, 342 mapValue interface{}, key string, opts *fieldOptionsWithContext, fullName string) error { 343 if mapValue == nil { 344 if opts.optional() { 345 return nil 346 } 347 348 return fmt.Errorf("field %s mustn't be nil", key) 349 } 350 351 maybeNewValue(field, value) 352 353 fieldKind := Deref(field.Type).Kind() 354 switch fieldKind { 355 case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct: 356 return u.processFieldNotFromString(field, value, mapValue, opts, fullName) 357 default: 358 if u.opts.fromString || opts.fromString() { 359 valueKind := reflect.TypeOf(mapValue).Kind() 360 if valueKind != reflect.String { 361 return fmt.Errorf("error: the value in map is not string, but %s", valueKind) 362 } 363 364 options := opts.options() 365 if len(options) > 0 { 366 if !stringx.Contains(options, mapValue.(string)) { 367 return fmt.Errorf(`error: value "%s" for field "%s" is not defined in options "%v"`, 368 mapValue, key, options) 369 } 370 } 371 372 return fillPrimitive(field.Type, value, mapValue, opts, fullName) 373 } 374 375 return u.processFieldNotFromString(field, value, mapValue, opts, fullName) 376 } 377 } 378 379 func (u *Unmarshaler) processNamedFieldWithoutValue(field reflect.StructField, value reflect.Value, 380 opts *fieldOptionsWithContext, fullName string) error { 381 derefedType := Deref(field.Type) 382 fieldKind := derefedType.Kind() 383 if defaultValue, ok := opts.getDefault(); ok { 384 if field.Type.Kind() == reflect.Ptr { 385 maybeNewValue(field, value) 386 value = value.Elem() 387 } 388 if derefedType == durationType { 389 return fillDurationValue(fieldKind, value, defaultValue) 390 } 391 392 switch fieldKind { 393 case reflect.Array, reflect.Slice: 394 return u.fillSliceWithDefault(derefedType, value, defaultValue) 395 default: 396 return setValue(fieldKind, value, defaultValue) 397 } 398 } 399 400 switch fieldKind { 401 case reflect.Array, reflect.Map, reflect.Slice: 402 if !opts.optional() { 403 return u.processFieldNotFromString(field, value, emptyMap, opts, fullName) 404 } 405 case reflect.Struct: 406 if !opts.optional() { 407 required, err := structValueRequired(u.key, derefedType) 408 if err != nil { 409 return err 410 } 411 if required { 412 return fmt.Errorf("%q is not set", fullName) 413 } 414 return u.processFieldNotFromString(field, value, emptyMap, opts, fullName) 415 } 416 default: 417 if !opts.optional() { 418 return newInitError(fullName) 419 } 420 } 421 422 return nil 423 } 424 425 func (u *Unmarshaler) fillMap(field reflect.StructField, value reflect.Value, mapValue interface{}) error { 426 if !value.CanSet() { 427 return errValueNotSettable 428 } 429 430 fieldKeyType := field.Type.Key() 431 fieldElemType := field.Type.Elem() 432 targetValue, err := u.generateMap(fieldKeyType, fieldElemType, mapValue) 433 if err != nil { 434 return err 435 } 436 437 value.Set(targetValue) 438 return nil 439 } 440 441 func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value, mapValue interface{}) error { 442 if !value.CanSet() { 443 return errValueNotSettable 444 } 445 446 baseType := fieldType.Elem() 447 baseKind := baseType.Kind() 448 dereffedBaseType := Deref(baseType) 449 dereffedBaseKind := dereffedBaseType.Kind() 450 refValue := reflect.ValueOf(mapValue) 451 conv := reflect.MakeSlice(reflect.SliceOf(baseType), refValue.Len(), refValue.Cap()) 452 453 var valid bool 454 for i := 0; i < refValue.Len(); i++ { 455 ithValue := refValue.Index(i).Interface() 456 if ithValue == nil { 457 continue 458 } 459 460 valid = true 461 switch dereffedBaseKind { 462 case reflect.Struct: 463 target := reflect.New(dereffedBaseType) 464 if err := u.Unmarshal(ithValue.(map[string]interface{}), target.Interface()); err != nil { 465 return err 466 } 467 468 if baseKind == reflect.Ptr { 469 conv.Index(i).Set(target) 470 } else { 471 conv.Index(i).Set(target.Elem()) 472 } 473 case reflect.Slice: 474 if err := u.fillSlice(dereffedBaseType, conv.Index(i), ithValue); err != nil { 475 return err 476 } 477 default: 478 if err := u.fillSliceValue(conv, i, dereffedBaseKind, ithValue); err != nil { 479 return err 480 } 481 } 482 } 483 484 if valid { 485 value.Set(conv) 486 } 487 488 return nil 489 } 490 491 func (u *Unmarshaler) fillSliceFromString(fieldType reflect.Type, value reflect.Value, mapValue interface{}) error { 492 var slice []interface{} 493 if err := jsonx.UnmarshalFromString(mapValue.(string), &slice); err != nil { 494 return err 495 } 496 497 baseFieldType := Deref(fieldType.Elem()) 498 baseFieldKind := baseFieldType.Kind() 499 conv := reflect.MakeSlice(reflect.SliceOf(baseFieldType), len(slice), cap(slice)) 500 501 for i := 0; i < len(slice); i++ { 502 if err := u.fillSliceValue(conv, i, baseFieldKind, slice[i]); err != nil { 503 return err 504 } 505 } 506 507 value.Set(conv) 508 return nil 509 } 510 511 func (u *Unmarshaler) fillSliceValue(slice reflect.Value, index int, 512 baseKind reflect.Kind, value interface{}) error { 513 ithVal := slice.Index(index) 514 switch v := value.(type) { 515 case json.Number: 516 return setValue(baseKind, ithVal, v.String()) 517 default: 518 // don't need to consider the difference between int, int8, int16, int32, int64, 519 // uint, uint8, uint16, uint32, uint64, because they're handled as json.Number. 520 if ithVal.Kind() == reflect.Ptr { 521 baseType := Deref(ithVal.Type()) 522 if baseType.Kind() != reflect.TypeOf(value).Kind() { 523 return errTypeMismatch 524 } 525 526 target := reflect.New(baseType).Elem() 527 target.Set(reflect.ValueOf(value)) 528 ithVal.Set(target.Addr()) 529 return nil 530 } 531 532 if ithVal.Kind() != reflect.TypeOf(value).Kind() { 533 return errTypeMismatch 534 } 535 536 ithVal.Set(reflect.ValueOf(value)) 537 return nil 538 } 539 } 540 541 func (u *Unmarshaler) fillSliceWithDefault(derefedType reflect.Type, value reflect.Value, 542 defaultValue string) error { 543 baseFieldType := Deref(derefedType.Elem()) 544 baseFieldKind := baseFieldType.Kind() 545 defaultCacheLock.Lock() 546 slice, ok := defaultCache[defaultValue] 547 defaultCacheLock.Unlock() 548 if !ok { 549 if baseFieldKind == reflect.String { 550 slice = parseGroupedSegments(defaultValue) 551 } else if err := jsonx.UnmarshalFromString(defaultValue, &slice); err != nil { 552 return err 553 } 554 555 defaultCacheLock.Lock() 556 defaultCache[defaultValue] = slice 557 defaultCacheLock.Unlock() 558 } 559 560 return u.fillSlice(derefedType, value, slice) 561 } 562 563 func (u *Unmarshaler) generateMap(keyType, elemType reflect.Type, mapValue interface{}) (reflect.Value, error) { 564 mapType := reflect.MapOf(keyType, elemType) 565 valueType := reflect.TypeOf(mapValue) 566 if mapType == valueType { 567 return reflect.ValueOf(mapValue), nil 568 } 569 570 refValue := reflect.ValueOf(mapValue) 571 targetValue := reflect.MakeMapWithSize(mapType, refValue.Len()) 572 fieldElemKind := elemType.Kind() 573 dereffedElemType := Deref(elemType) 574 dereffedElemKind := dereffedElemType.Kind() 575 576 for _, key := range refValue.MapKeys() { 577 keythValue := refValue.MapIndex(key) 578 keythData := keythValue.Interface() 579 580 switch dereffedElemKind { 581 case reflect.Slice: 582 target := reflect.New(dereffedElemType) 583 if err := u.fillSlice(elemType, target.Elem(), keythData); err != nil { 584 return emptyValue, err 585 } 586 587 targetValue.SetMapIndex(key, target.Elem()) 588 case reflect.Struct: 589 keythMap, ok := keythData.(map[string]interface{}) 590 if !ok { 591 return emptyValue, errTypeMismatch 592 } 593 594 target := reflect.New(dereffedElemType) 595 if err := u.Unmarshal(keythMap, target.Interface()); err != nil { 596 return emptyValue, err 597 } 598 599 if fieldElemKind == reflect.Ptr { 600 targetValue.SetMapIndex(key, target) 601 } else { 602 targetValue.SetMapIndex(key, target.Elem()) 603 } 604 case reflect.Map: 605 keythMap, ok := keythData.(map[string]interface{}) 606 if !ok { 607 return emptyValue, errTypeMismatch 608 } 609 610 innerValue, err := u.generateMap(elemType.Key(), elemType.Elem(), keythMap) 611 if err != nil { 612 return emptyValue, err 613 } 614 615 targetValue.SetMapIndex(key, innerValue) 616 default: 617 switch v := keythData.(type) { 618 case bool: 619 targetValue.SetMapIndex(key, reflect.ValueOf(v)) 620 case string: 621 targetValue.SetMapIndex(key, reflect.ValueOf(v)) 622 case json.Number: 623 target := reflect.New(dereffedElemType) 624 if err := setValue(dereffedElemKind, target.Elem(), v.String()); err != nil { 625 return emptyValue, err 626 } 627 628 targetValue.SetMapIndex(key, target.Elem()) 629 default: 630 targetValue.SetMapIndex(key, keythValue) 631 } 632 } 633 } 634 635 return targetValue, nil 636 } 637 638 func (u *Unmarshaler) parseOptionsWithContext(field reflect.StructField, m Valuer, fullName string) ( 639 string, *fieldOptionsWithContext, error) { 640 key, options, err := parseKeyAndOptions(u.key, field) 641 if err != nil { 642 return "", nil, err 643 } else if options == nil { 644 return key, nil, nil 645 } 646 647 optsWithContext, err := options.toOptionsWithContext(key, m, fullName) 648 if err != nil { 649 return "", nil, err 650 } 651 652 return key, optsWithContext, nil 653 } 654 655 // WithStringValues customizes a Unmarshaler with number values from strings. 656 func WithStringValues() UnmarshalOption { 657 return func(opt *unmarshalOptions) { 658 opt.fromString = true 659 } 660 } 661 662 // WithCanonicalKeyFunc customizes a Unmarshaler with Canonical Key func 663 func WithCanonicalKeyFunc(f func(string) string) UnmarshalOption { 664 return func(opt *unmarshalOptions) { 665 opt.canonicalKey = f 666 } 667 } 668 669 func fillDurationValue(fieldKind reflect.Kind, value reflect.Value, dur string) error { 670 d, err := time.ParseDuration(dur) 671 if err != nil { 672 return err 673 } 674 675 if fieldKind == reflect.Ptr { 676 value.Elem().Set(reflect.ValueOf(d)) 677 } else { 678 value.Set(reflect.ValueOf(d)) 679 } 680 681 return nil 682 } 683 684 func fillPrimitive(fieldType reflect.Type, value reflect.Value, mapValue interface{}, 685 opts *fieldOptionsWithContext, fullName string) error { 686 if !value.CanSet() { 687 return errValueNotSettable 688 } 689 690 baseType := Deref(fieldType) 691 if fieldType.Kind() == reflect.Ptr { 692 target := reflect.New(baseType).Elem() 693 switch mapValue.(type) { 694 case string, json.Number: 695 value.Set(target.Addr()) 696 value = target 697 } 698 } 699 700 switch v := mapValue.(type) { 701 case string: 702 return validateAndSetValue(baseType.Kind(), value, v, opts) 703 case json.Number: 704 if err := validateJsonNumberRange(v, opts); err != nil { 705 return err 706 } 707 return setValue(baseType.Kind(), value, v.String()) 708 default: 709 return newTypeMismatchError(fullName) 710 } 711 } 712 713 func fillWithSameType(field reflect.StructField, value reflect.Value, mapValue interface{}, 714 opts *fieldOptionsWithContext) error { 715 if !value.CanSet() { 716 return errValueNotSettable 717 } 718 719 if err := validateValueRange(mapValue, opts); err != nil { 720 return err 721 } 722 723 if field.Type.Kind() == reflect.Ptr { 724 baseType := Deref(field.Type) 725 target := reflect.New(baseType).Elem() 726 target.Set(reflect.ValueOf(mapValue)) 727 value.Set(target.Addr()) 728 } else { 729 value.Set(reflect.ValueOf(mapValue)) 730 } 731 732 return nil 733 } 734 735 // getValue gets the value for the specific key, the key can be in the format of parentKey.childKey 736 func getValue(m Valuer, key string) (interface{}, bool) { 737 keys := readKeys(key) 738 return getValueWithChainedKeys(m, keys) 739 } 740 741 func getValueWithChainedKeys(m Valuer, keys []string) (interface{}, bool) { 742 if len(keys) == 1 { 743 v, ok := m.Value(keys[0]) 744 return v, ok 745 } 746 747 if len(keys) > 1 { 748 if v, ok := m.Value(keys[0]); ok { 749 if nextm, ok := v.(map[string]interface{}); ok { 750 return getValueWithChainedKeys(MapValuer(nextm), keys[1:]) 751 } 752 } 753 } 754 755 return nil, false 756 } 757 758 func join(elem ...string) string { 759 var builder strings.Builder 760 761 var fillSep bool 762 for _, e := range elem { 763 if len(e) == 0 { 764 continue 765 } 766 767 if fillSep { 768 builder.WriteByte(delimiter) 769 } else { 770 fillSep = true 771 } 772 773 builder.WriteString(e) 774 } 775 776 return builder.String() 777 } 778 779 func newInitError(name string) error { 780 return fmt.Errorf("field %s is not set", name) 781 } 782 783 func newTypeMismatchError(name string) error { 784 return fmt.Errorf("error: type mismatch for field %s", name) 785 } 786 787 func readKeys(key string) []string { 788 cacheKeysLock.Lock() 789 keys, ok := cacheKeys[key] 790 cacheKeysLock.Unlock() 791 if ok { 792 return keys 793 } 794 795 keys = strings.FieldsFunc(key, func(c rune) bool { 796 return c == delimiter 797 }) 798 cacheKeysLock.Lock() 799 cacheKeys[key] = keys 800 cacheKeysLock.Unlock() 801 802 return keys 803 }