LEFT | RIGHT |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package json implements encoding and decoding of JSON objects as defined in | 5 // Package json implements encoding and decoding of JSON objects as defined in |
6 // RFC 4627. | 6 // RFC 4627. |
7 // | 7 // |
8 // See "JSON and Go" for an introduction to this package: | 8 // See "JSON and Go" for an introduction to this package: |
9 // http://golang.org/doc/articles/json_and_go.html | 9 // http://golang.org/doc/articles/json_and_go.html |
10 package json | 10 package json |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 continue | 611 continue |
612 } | 612 } |
613 name, opts := parseTag(tag) | 613 name, opts := parseTag(tag) |
614 if !isValidTag(name) { | 614 if !isValidTag(name) { |
615 name = "" | 615 name = "" |
616 } | 616 } |
617 index := make([]int, len(f.index)+1) | 617 index := make([]int, len(f.index)+1) |
618 copy(index, f.index) | 618 copy(index, f.index) |
619 index[len(f.index)] = i | 619 index[len(f.index)] = i |
620 // Record found field and index sequence. | 620 // Record found field and index sequence. |
621 if name != "" || !sf.Anonymous { | 621 if name != "" || !sf.Anonymous { |
622 tagged := name != "" | 622 tagged := name != "" |
623 if name == "" { | 623 if name == "" { |
624 name = sf.Name | 624 name = sf.Name |
625 } | 625 } |
626 fields = append(fields, field{name, tagg
ed, index, sf.Type, | 626 fields = append(fields, field{name, tagg
ed, index, sf.Type, |
627 opts.Contains("omitempty"), opts
.Contains("string")}) | 627 opts.Contains("omitempty"), opts
.Contains("string")}) |
628 if count[f.typ] > 1 { | 628 if count[f.typ] > 1 { |
| 629 // If there were multiple instan
ces, add a second, |
| 630 // so that the annihilation code
will see a duplicate. |
| 631 // It only cares about the disti
nction between 1 or 2, |
| 632 // so don't bother generating an
y more copies. |
629 fields = append(fields, fields[l
en(fields)-1]) | 633 fields = append(fields, fields[l
en(fields)-1]) |
630 } | 634 } |
631 continue | 635 continue |
632 } | 636 } |
633 | 637 |
634 // Record new anonymous struct to explore in nex
t round. | 638 // Record new anonymous struct to explore in nex
t round. |
635 ft := sf.Type | 639 ft := sf.Type |
636 if ft.Name() == "" { | 640 if ft.Name() == "" { |
| 641 // Must be pointer. |
637 ft = ft.Elem() | 642 ft = ft.Elem() |
638 } | 643 } |
639 nextCount[ft]++ | 644 nextCount[ft]++ |
640 if nextCount[ft] == 1 { | 645 if nextCount[ft] == 1 { |
641 next = append(next, field{name: ft.Name(
), index: index, typ: ft}) | 646 next = append(next, field{name: ft.Name(
), index: index, typ: ft}) |
642 } | 647 } |
643 } | 648 } |
644 } | 649 } |
645 } | 650 } |
646 | 651 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 } | 694 } |
690 | 695 |
691 fieldCache.Lock() | 696 fieldCache.Lock() |
692 if fieldCache.m == nil { | 697 if fieldCache.m == nil { |
693 fieldCache.m = map[reflect.Type][]field{} | 698 fieldCache.m = map[reflect.Type][]field{} |
694 } | 699 } |
695 fieldCache.m[t] = f | 700 fieldCache.m[t] = f |
696 fieldCache.Unlock() | 701 fieldCache.Unlock() |
697 return f | 702 return f |
698 } | 703 } |
LEFT | RIGHT |