-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConvertTo-YamlRepresentationNode.ps1
More file actions
114 lines (105 loc) · 3.99 KB
/
Copy pathConvertTo-YamlRepresentationNode.ps1
File metadata and controls
114 lines (105 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
function ConvertTo-YamlRepresentationNode {
<#
.SYNOPSIS
Converts one representation graph to a lossless emission graph.
#>
[CmdletBinding()]
[OutputType([pscustomobject])]
param (
[Parameter(Mandatory)]
[pscustomobject] $Node,
[Parameter(Mandatory)]
[pscustomobject] $State
)
$orderedNodes = [System.Collections.Generic.List[object]]::new()
$visited = [System.Collections.Generic.HashSet[int]]::new()
$aliasTargets = [System.Collections.Generic.HashSet[int]]::new()
$pending = [System.Collections.Generic.Stack[object]]::new()
$pending.Push($Node)
while ($pending.Count -gt 0) {
$current = $pending.Pop()
if ($current.Kind -eq 'Alias') {
[void] $aliasTargets.Add($current.Target.Id)
if (-not $visited.Contains($current.Target.Id)) {
$pending.Push($current.Target)
}
continue
}
if (-not $visited.Add($current.Id)) {
continue
}
$orderedNodes.Add($current)
if ($current.Kind -eq 'Sequence') {
for ($index = $current.Items.Count - 1; $index -ge 0; $index--) {
$pending.Push($current.Items[$index])
}
} elseif ($current.Kind -eq 'Mapping') {
for ($index = $current.Entries.Count - 1; $index -ge 0; $index--) {
$pending.Push($current.Entries[$index].Value)
$pending.Push($current.Entries[$index].Key)
}
}
}
$anchorNames = [System.Collections.Generic.Dictionary[int, string]]::new()
foreach ($source in $orderedNodes) {
if (-not [string]::IsNullOrEmpty($source.Anchor) -or
$aliasTargets.Contains($source.Id)) {
$anchorNames[$source.Id] = 'id{0:d3}' -f $State.NextAnchor
$State.NextAnchor++
}
}
$nodes = [System.Collections.Generic.Dictionary[int, object]]::new()
foreach ($source in $orderedNodes) {
$target = New-YamlEmissionNode -Kind $source.Kind
$target.Tag = [string] $source.Tag
$target.HasUnknownTag = [bool] $source.HasUnknownTag
if ($anchorNames.ContainsKey($source.Id)) {
$target.Anchor = $anchorNames[$source.Id]
$target.ReferenceId = [long] $source.Id
}
if ($source.Kind -eq 'Scalar') {
$target.Value = [string] $source.Value
$target.Style = 'DoubleQuoted'
if ([string]::IsNullOrEmpty($source.Tag) -and
-not $source.HasUnknownTag -and $source.IsPlainImplicit) {
$resolved = (Resolve-YamlScalar -Node $source).Value
$effectiveTag = Get-YamlEffectiveTag -Node $source -Value $resolved
if ($effectiveTag -cne 'tag:yaml.org,2002:str') {
$target.Style = 'Plain'
}
}
}
$nodes[$source.Id] = $target
}
foreach ($source in $orderedNodes) {
$target = $nodes[$source.Id]
if ($source.Kind -eq 'Sequence') {
foreach ($item in $source.Items) {
$itemId = if ($item.Kind -eq 'Alias') {
$item.Target.Id
} else {
$item.Id
}
$target.Items.Add($nodes[$itemId])
}
} elseif ($source.Kind -eq 'Mapping') {
foreach ($entry in $source.Entries) {
$keyId = if ($entry.Key.Kind -eq 'Alias') {
$entry.Key.Target.Id
} else {
$entry.Key.Id
}
$valueId = if ($entry.Value.Kind -eq 'Alias') {
$entry.Value.Target.Id
} else {
$entry.Value.Id
}
$target.Entries.Add([pscustomobject]@{
Key = $nodes[$keyId]
Value = $nodes[$valueId]
})
}
}
}
Write-Output -InputObject $nodes[$Node.Id] -NoEnumerate
}