98 // puts the results into p.event and returns the event type. |
98 // puts the results into p.event and returns the event type. |
99 func (p *parser) peek() yaml_event_type_t { |
99 func (p *parser) peek() yaml_event_type_t { |
100 if p.event.typ != yaml_NO_EVENT { |
100 if p.event.typ != yaml_NO_EVENT { |
101 return p.event.typ |
101 return p.event.typ |
102 } |
102 } |
103 if !yaml_parser_parse(&p.parser, &p.event) { |
103 // It's curious choice from the underlying API to generally return a |
|
104 // positive result on success, but on this case return true in an error |
|
105 // scenario. This was the source of bugs in the past (issue #666). |
|
106 if !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR { |
104 p.fail() |
107 p.fail() |
105 } |
108 } |
106 return p.event.typ |
109 return p.event.typ |
107 } |
110 } |
108 |
111 |
806 } else if outt.Key() == ifaceType { |
811 } else if outt.Key() == ifaceType { |
807 d.generalMapType = outt |
812 d.generalMapType = outt |
808 } |
813 } |
809 } |
814 } |
810 |
815 |
|
816 mergedFields := d.mergedFields |
|
817 d.mergedFields = nil |
|
818 |
|
819 var mergeNode *Node |
|
820 |
811 mapIsNew := false |
821 mapIsNew := false |
812 if out.IsNil() { |
822 if out.IsNil() { |
813 out.Set(reflect.MakeMap(outt)) |
823 out.Set(reflect.MakeMap(outt)) |
814 mapIsNew = true |
824 mapIsNew = true |
815 } |
825 } |
816 for i := 0; i < l; i += 2 { |
826 for i := 0; i < l; i += 2 { |
817 if isMerge(n.Content[i]) { |
827 if isMerge(n.Content[i]) { |
818 d.merge(n.Content[i+1], out) |
828 mergeNode = n.Content[i+1] |
819 continue |
829 continue |
820 } |
830 } |
821 k := reflect.New(kt).Elem() |
831 k := reflect.New(kt).Elem() |
822 if d.unmarshal(n.Content[i], k) { |
832 if d.unmarshal(n.Content[i], k) { |
|
833 if mergedFields != nil { |
|
834 ki := k.Interface() |
|
835 if mergedFields[ki] { |
|
836 continue |
|
837 } |
|
838 mergedFields[ki] = true |
|
839 } |
823 kkind := k.Kind() |
840 kkind := k.Kind() |
824 if kkind == reflect.Interface { |
841 if kkind == reflect.Interface { |
825 kkind = k.Elem().Kind() |
842 kkind = k.Elem().Kind() |
826 } |
843 } |
827 if kkind == reflect.Map || kkind == reflect.Slice { |
844 if kkind == reflect.Map || kkind == reflect.Slice { |
831 if d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) { |
848 if d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) { |
832 out.SetMapIndex(k, e) |
849 out.SetMapIndex(k, e) |
833 } |
850 } |
834 } |
851 } |
835 } |
852 } |
|
853 |
|
854 d.mergedFields = mergedFields |
|
855 if mergeNode != nil { |
|
856 d.merge(n, mergeNode, out) |
|
857 } |
|
858 |
836 d.stringMapType = stringMapType |
859 d.stringMapType = stringMapType |
837 d.generalMapType = generalMapType |
860 d.generalMapType = generalMapType |
838 return true |
861 return true |
839 } |
862 } |
840 |
863 |
859 |
883 |
860 var inlineMap reflect.Value |
884 var inlineMap reflect.Value |
861 var elemType reflect.Type |
885 var elemType reflect.Type |
862 if sinfo.InlineMap != -1 { |
886 if sinfo.InlineMap != -1 { |
863 inlineMap = out.Field(sinfo.InlineMap) |
887 inlineMap = out.Field(sinfo.InlineMap) |
864 inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) |
|
865 elemType = inlineMap.Type().Elem() |
888 elemType = inlineMap.Type().Elem() |
866 } |
889 } |
867 |
890 |
868 for _, index := range sinfo.InlineUnmarshalers { |
891 for _, index := range sinfo.InlineUnmarshalers { |
869 field := d.fieldByIndex(n, out, index) |
892 field := d.fieldByIndex(n, out, index) |
870 d.prepare(n, field) |
893 d.prepare(n, field) |
871 } |
894 } |
872 |
895 |
|
896 mergedFields := d.mergedFields |
|
897 d.mergedFields = nil |
|
898 var mergeNode *Node |
873 var doneFields []bool |
899 var doneFields []bool |
874 if d.uniqueKeys { |
900 if d.uniqueKeys { |
875 doneFields = make([]bool, len(sinfo.FieldsList)) |
901 doneFields = make([]bool, len(sinfo.FieldsList)) |
876 } |
902 } |
877 name := settableValueOf("") |
903 name := settableValueOf("") |
878 l := len(n.Content) |
904 l := len(n.Content) |
879 for i := 0; i < l; i += 2 { |
905 for i := 0; i < l; i += 2 { |
880 ni := n.Content[i] |
906 ni := n.Content[i] |
881 if isMerge(ni) { |
907 if isMerge(ni) { |
882 d.merge(n.Content[i+1], out) |
908 mergeNode = n.Content[i+1] |
883 continue |
909 continue |
884 } |
910 } |
885 if !d.unmarshal(ni, name) { |
911 if !d.unmarshal(ni, name) { |
886 continue |
912 continue |
887 } |
913 } |
888 if info, ok := sinfo.FieldsMap[name.String()]; ok { |
914 sname := name.String() |
|
915 if mergedFields != nil { |
|
916 if mergedFields[sname] { |
|
917 continue |
|
918 } |
|
919 mergedFields[sname] = true |
|
920 } |
|
921 if info, ok := sinfo.FieldsMap[sname]; ok { |
889 if d.uniqueKeys { |
922 if d.uniqueKeys { |
890 if doneFields[info.Id] { |
923 if doneFields[info.Id] { |
891 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type())) |
924 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type())) |
892 continue |
925 continue |
893 } |
926 } |
909 inlineMap.SetMapIndex(name, value) |
942 inlineMap.SetMapIndex(name, value) |
910 } else if d.knownFields { |
943 } else if d.knownFields { |
911 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type())) |
944 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type())) |
912 } |
945 } |
913 } |
946 } |
|
947 |
|
948 d.mergedFields = mergedFields |
|
949 if mergeNode != nil { |
|
950 d.merge(n, mergeNode, out) |
|
951 } |
914 return true |
952 return true |
915 } |
953 } |
916 |
954 |
917 func failWantMap() { |
955 func failWantMap() { |
918 failf("map merge requires map or sequence of maps as the value") |
956 failf("map merge requires map or sequence of maps as the value") |
919 } |
957 } |
920 |
958 |
921 func (d *decoder) merge(n *Node, out reflect.Value) { |
959 func (d *decoder) merge(parent *Node, merge *Node, out reflect.Value) { |
922 switch n.Kind { |
960 mergedFields := d.mergedFields |
|
961 if mergedFields == nil { |
|
962 d.mergedFields = make(map[interface{}]bool) |
|
963 for i := 0; i < len(parent.Content); i += 2 { |
|
964 k := reflect.New(ifaceType).Elem() |
|
965 if d.unmarshal(parent.Content[i], k) { |
|
966 d.mergedFields[k.Interface()] = true |
|
967 } |
|
968 } |
|
969 } |
|
970 |
|
971 switch merge.Kind { |
923 case MappingNode: |
972 case MappingNode: |
924 d.unmarshal(n, out) |
973 d.unmarshal(merge, out) |
925 case AliasNode: |
974 case AliasNode: |
926 if n.Alias != nil && n.Alias.Kind != MappingNode { |
975 if merge.Alias != nil && merge.Alias.Kind != MappingNode { |
927 failWantMap() |
976 failWantMap() |
928 } |
977 } |
929 d.unmarshal(n, out) |
978 d.unmarshal(merge, out) |
930 case SequenceNode: |
979 case SequenceNode: |
931 // Step backwards as earlier nodes take precedence. |
980 for i := 0; i < len(merge.Content); i++ { |
932 for i := len(n.Content) - 1; i >= 0; i-- { |
981 ni := merge.Content[i] |
933 ni := n.Content[i] |
|
934 if ni.Kind == AliasNode { |
982 if ni.Kind == AliasNode { |
935 if ni.Alias != nil && ni.Alias.Kind != MappingNode { |
983 if ni.Alias != nil && ni.Alias.Kind != MappingNode { |
936 failWantMap() |
984 failWantMap() |
937 } |
985 } |
938 } else if ni.Kind != MappingNode { |
986 } else if ni.Kind != MappingNode { |