yq/pkg/yqlib/candidate_node_yaml.go

248 lines
6.2 KiB
Go
Raw Normal View History

2023-04-11 05:33:32 +00:00
package yqlib
import (
"fmt"
yaml "gopkg.in/yaml.v3"
)
func MapYamlStyle(original yaml.Style) Style {
switch original {
case yaml.TaggedStyle:
return TaggedStyle
case yaml.DoubleQuotedStyle:
return DoubleQuotedStyle
case yaml.SingleQuotedStyle:
return SingleQuotedStyle
case yaml.LiteralStyle:
return LiteralStyle
case yaml.FoldedStyle:
return FoldedStyle
case yaml.FlowStyle:
return FlowStyle
2023-04-15 05:54:44 +00:00
case 0:
return 0
2023-04-11 05:33:32 +00:00
}
2023-04-15 05:54:44 +00:00
return Style(original)
2023-04-11 05:33:32 +00:00
}
func MapToYamlStyle(original Style) yaml.Style {
switch original {
case TaggedStyle:
return yaml.TaggedStyle
case DoubleQuotedStyle:
return yaml.DoubleQuotedStyle
case SingleQuotedStyle:
return yaml.SingleQuotedStyle
case LiteralStyle:
return yaml.LiteralStyle
case FoldedStyle:
return yaml.FoldedStyle
case FlowStyle:
return yaml.FlowStyle
2023-04-15 05:54:44 +00:00
case 0:
return 0
2023-04-11 05:33:32 +00:00
}
2023-04-15 05:54:44 +00:00
return yaml.Style(original)
2023-04-11 05:33:32 +00:00
}
2023-04-15 04:24:39 +00:00
func (o *CandidateNode) copyFromYamlNode(node *yaml.Node, anchorMap map[string]*CandidateNode) {
2023-04-11 05:33:32 +00:00
o.Style = MapYamlStyle(node.Style)
o.Tag = node.Tag
o.Value = node.Value
o.Anchor = node.Anchor
2023-04-15 04:24:39 +00:00
if o.Anchor != "" {
anchorMap[o.Anchor] = o
log.Debug("set anchor %v to %v", o.Anchor, NodeToString(o))
}
2023-04-15 04:48:35 +00:00
// its a single alias
if node.Alias != nil && node.Alias.Anchor != "" {
2023-04-15 04:24:39 +00:00
o.Alias = anchorMap[node.Alias.Anchor]
log.Debug("set alias to %v", NodeToString(anchorMap[node.Alias.Anchor]))
}
2023-04-11 05:33:32 +00:00
o.HeadComment = node.HeadComment
o.LineComment = node.LineComment
o.FootComment = node.FootComment
o.Line = node.Line
o.Column = node.Column
}
func (o *CandidateNode) copyToYamlNode(node *yaml.Node) {
node.Style = MapToYamlStyle(o.Style)
node.Tag = o.Tag
node.Value = o.Value
node.Anchor = o.Anchor
// node.Alias = TODO - find Alias in our own structure
// might need to be a post process thing
node.HeadComment = o.HeadComment
2023-04-15 04:10:12 +00:00
2023-04-11 05:33:32 +00:00
node.LineComment = o.LineComment
node.FootComment = o.FootComment
node.Line = o.Line
node.Column = o.Column
}
2023-04-15 04:24:39 +00:00
func (o *CandidateNode) decodeIntoChild(childNode *yaml.Node, anchorMap map[string]*CandidateNode) (*CandidateNode, error) {
2023-04-13 04:34:34 +00:00
newChild := o.CreateChild()
// null yaml.Nodes to not end up calling UnmarshalYAML
// so we call it explicitly
if childNode.Tag == "!!null" {
newChild.Kind = ScalarNode
2023-04-15 04:24:39 +00:00
newChild.copyFromYamlNode(childNode, anchorMap)
2023-04-13 04:34:34 +00:00
return newChild, nil
}
2023-04-15 04:24:39 +00:00
err := newChild.UnmarshalYAML(childNode, anchorMap)
2023-04-13 04:34:34 +00:00
return newChild, err
}
2023-04-15 04:24:39 +00:00
func (o *CandidateNode) UnmarshalYAML(node *yaml.Node, anchorMap map[string]*CandidateNode) error {
2023-04-13 04:34:34 +00:00
log.Debugf("UnmarshalYAML %v", node.Tag)
2023-04-11 05:33:32 +00:00
switch node.Kind {
2023-06-05 22:27:59 +00:00
// case yaml.DocumentNode:
// log.Debugf("UnmarshalYAML - a document")
// o.Kind = DocumentNode
// o.copyFromYamlNode(node, anchorMap)
// if len(node.Content) == 0 {
// return nil
// }
// singleChild, err := o.decodeIntoChild(node.Content[0], anchorMap)
// if err != nil {
// return err
// }
// o.Content = []*CandidateNode{singleChild}
// log.Debugf("UnmarshalYAML - finished document node")
// return nil
2023-04-11 05:33:32 +00:00
case yaml.AliasNode:
2023-04-13 04:34:34 +00:00
log.Debug("UnmarshalYAML - alias from yaml: %v", o.Tag)
2023-04-11 05:33:32 +00:00
o.Kind = AliasNode
2023-04-15 04:24:39 +00:00
o.copyFromYamlNode(node, anchorMap)
2023-04-11 05:33:32 +00:00
return nil
case yaml.ScalarNode:
2023-04-13 04:34:34 +00:00
log.Debugf("UnmarshalYAML - a scalar")
2023-04-11 05:33:32 +00:00
o.Kind = ScalarNode
2023-04-15 04:24:39 +00:00
o.copyFromYamlNode(node, anchorMap)
2023-04-11 05:33:32 +00:00
return nil
case yaml.MappingNode:
2023-04-13 04:34:34 +00:00
log.Debugf("UnmarshalYAML - a mapping node")
2023-04-11 05:33:32 +00:00
o.Kind = MappingNode
2023-04-15 04:24:39 +00:00
o.copyFromYamlNode(node, anchorMap)
2023-04-11 05:33:32 +00:00
o.Content = make([]*CandidateNode, len(node.Content))
for i := 0; i < len(node.Content); i += 2 {
2023-04-13 04:34:34 +00:00
2023-04-15 04:24:39 +00:00
keyNode, err := o.decodeIntoChild(node.Content[i], anchorMap)
2023-04-11 05:33:32 +00:00
if err != nil {
return err
}
2023-04-13 04:34:34 +00:00
keyNode.IsMapKey = true
2023-04-15 04:24:39 +00:00
valueNode, err := o.decodeIntoChild(node.Content[i+1], anchorMap)
2023-04-11 05:33:32 +00:00
if err != nil {
return err
}
2023-04-13 04:34:34 +00:00
valueNode.Key = keyNode
2023-04-11 05:33:32 +00:00
o.Content[i] = keyNode
o.Content[i+1] = valueNode
}
2023-04-15 04:10:12 +00:00
log.Debugf("UnmarshalYAML - finished mapping node")
2023-04-11 05:33:32 +00:00
return nil
case yaml.SequenceNode:
2023-04-13 04:34:34 +00:00
log.Debugf("UnmarshalYAML - a sequence: %v", len(node.Content))
2023-04-11 05:33:32 +00:00
o.Kind = SequenceNode
2023-04-15 05:54:44 +00:00
2023-04-15 04:24:39 +00:00
o.copyFromYamlNode(node, anchorMap)
2023-04-15 05:54:44 +00:00
log.Debugf("node Style: %v", node.Style)
log.Debugf("o Style: %v", o.Style)
2023-04-11 05:33:32 +00:00
o.Content = make([]*CandidateNode, len(node.Content))
2023-05-09 03:51:21 +00:00
for i := 0; i < len(node.Content); i++ {
2023-04-11 05:33:32 +00:00
keyNode := o.CreateChild()
2023-04-17 07:23:48 +00:00
keyNode.IsMapKey = true
2023-04-11 05:33:32 +00:00
keyNode.Tag = "!!int"
keyNode.Kind = ScalarNode
keyNode.Value = fmt.Sprintf("%v", i)
2023-04-15 04:24:39 +00:00
valueNode, err := o.decodeIntoChild(node.Content[i], anchorMap)
2023-04-11 05:33:32 +00:00
if err != nil {
return err
}
2023-04-13 04:34:34 +00:00
valueNode.Key = keyNode
2023-04-11 05:33:32 +00:00
o.Content[i] = valueNode
}
return nil
case 0:
// not sure when this happens
2023-04-15 04:24:39 +00:00
o.copyFromYamlNode(node, anchorMap)
2023-10-05 05:01:24 +00:00
log.Debugf("UnmarshalYAML - err.. %v", NodeToString(o))
2023-04-11 05:33:32 +00:00
return nil
default:
return fmt.Errorf("orderedMap: invalid yaml node")
}
}
2023-04-15 04:10:12 +00:00
func (o *CandidateNode) MarshalYAML() (*yaml.Node, error) {
2023-04-13 05:40:41 +00:00
log.Debug("MarshalYAML to yaml: %v", o.Tag)
2023-04-11 05:33:32 +00:00
switch o.Kind {
2023-06-05 22:27:59 +00:00
// case DocumentNode:
// log.Debug("MarshalYAML its a document")
// target := &yaml.Node{Kind: yaml.DocumentNode}
// o.copyToYamlNode(target)
// singleChild, err := o.Content[0].MarshalYAML()
// log.Debug("MarshalYAML its a document - singChild is %v", singleChild)
// if err != nil {
// return nil, err
// }
// target.Content = []*yaml.Node{singleChild}
// return target, nil
2023-04-11 05:33:32 +00:00
case AliasNode:
2023-04-13 05:40:41 +00:00
log.Debug("MarshalYAML - alias to yaml: %v", o.Tag)
2023-04-11 05:33:32 +00:00
target := &yaml.Node{Kind: yaml.AliasNode}
o.copyToYamlNode(target)
return target, nil
case ScalarNode:
2023-04-13 05:40:41 +00:00
log.Debug("MarshalYAML - scalar: %v", o.Value)
2023-04-11 05:33:32 +00:00
target := &yaml.Node{Kind: yaml.ScalarNode}
o.copyToYamlNode(target)
return target, nil
case MappingNode, SequenceNode:
targetKind := yaml.MappingNode
if o.Kind == SequenceNode {
targetKind = yaml.SequenceNode
}
target := &yaml.Node{Kind: targetKind}
o.copyToYamlNode(target)
2023-04-15 05:54:44 +00:00
log.Debugf("original style: %v", o.Style)
log.Debugf("original: %v, tag: %v, style: %v, kind: %v", NodeToString(o), target.Tag, target.Style, target.Kind == yaml.SequenceNode)
2023-04-11 05:33:32 +00:00
target.Content = make([]*yaml.Node, len(o.Content))
2023-05-09 03:51:21 +00:00
for i := 0; i < len(o.Content); i++ {
2023-04-15 04:10:12 +00:00
child, err := o.Content[i].MarshalYAML()
2023-04-11 05:33:32 +00:00
if err != nil {
return nil, err
}
target.Content[i] = child
}
return target, nil
}
target := &yaml.Node{}
o.copyToYamlNode(target)
return target, nil
}