Skip to content

Commit df242c0

Browse files
committed
clean up and implement the same for dictionary
1 parent 423d65b commit df242c0

File tree

4 files changed

+87
-24
lines changed

4 files changed

+87
-24
lines changed

sdk/provisioning/Azure.Provisioning/src/BicepDictionaryOfT.cs

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Linq;
99
using Azure.Provisioning.Expressions;
1010
using Azure.Provisioning.Primitives;
11+
using Azure.Provisioning.Utilities;
1112

1213
namespace Azure.Provisioning;
1314

@@ -58,7 +59,15 @@ internal override void Assign(IBicepValue source)
5859
{
5960
_values = typed._values;
6061
}
62+
63+
// Everything else is handled by the base Assign
6164
base.Assign(source);
65+
66+
// handle self in all the items
67+
foreach (var kv in _values)
68+
{
69+
SetSelfForItem(kv.Value, kv.Key);
70+
}
6271
}
6372

6473
/// <summary>
@@ -68,23 +77,78 @@ internal override void Assign(IBicepValue source)
6877
public static implicit operator BicepDictionary<T>(ProvisioningVariable reference) =>
6978
new(new BicepValueReference(reference, "{}"), BicepSyntax.Var(reference.BicepIdentifier)) { _isSecure = reference is ProvisioningParameter p && p.IsSecure };
7079

80+
private BicepValueReference? GetItemSelf(string key) =>
81+
_self is not null
82+
? new BicepDictionaryValueReference(_self.Construct, _self.PropertyName, _self.BicepPath?.ToArray(), key)
83+
: null;
84+
85+
private void SetSelfForItem(BicepValue<T> item, string key)
86+
{
87+
var itemSelf = GetItemSelf(key);
88+
item.SetSelf(itemSelf);
89+
}
90+
91+
private void RemoveSelfForItem(BicepValue<T> item)
92+
{
93+
item.SetSelf(null);
94+
}
95+
7196
/// <summary>
7297
/// Gets or sets a value in a BicepDictionary.
7398
/// </summary>
7499
/// <param name="key">Key of the value.</param>
75100
/// <returns>The value.</returns>
76101
public BicepValue<T> this[string key]
77102
{
78-
get => _values[key];
79-
set => _values[key] = value;
103+
get
104+
{
105+
if (_values.TryGetValue(key, out var value))
106+
{
107+
return value;
108+
}
109+
// the key does not exist, we put a value factory as the literal value of this bicep value
110+
// this would blow up when we try to compile it later, but it would be fine if we convert it to an expression
111+
return new BicepValue<T>(GetItemSelf(key), () => _values[key].Value);
112+
}
113+
114+
set
115+
{
116+
_values[key] = value;
117+
// update the _self pointing the new item
118+
SetSelfForItem(value, key);
119+
}
120+
}
121+
122+
public void Add(string key, BicepValue<T> value)
123+
{
124+
_values.Add(key, value);
125+
// update the _self pointing the new item
126+
SetSelfForItem(value, key);
127+
}
128+
129+
public void Add(KeyValuePair<string, BicepValue<T>> item)
130+
{
131+
_values.Add(item.Key, item.Value);
132+
// update the _self pointing the new item
133+
SetSelfForItem(item.Value, item.Key);
80134
}
81135

82-
public void Add(string key, BicepValue<T> value) => _values.Add(key, value);
83-
public void Add(KeyValuePair<string, BicepValue<T>> item) => _values.Add(item.Key, item.Value);
136+
public bool Remove(string key)
137+
{
138+
var removedItem = _values[key];
139+
// maintain the self reference for the removed item
140+
RemoveSelfForItem(removedItem);
141+
return _values.Remove(key);
142+
}
84143

85-
// TODO: Decide whether it's important to "unlink" resources on removal
86-
public bool Remove(string key) => _values.Remove(key);
87-
public void Clear() => _values.Clear();
144+
public void Clear()
145+
{
146+
foreach (var kv in _values)
147+
{
148+
RemoveSelfForItem(kv.Value);
149+
}
150+
_values.Clear();
151+
}
88152

89153
public ICollection<string> Keys => _values.Keys;
90154
public ICollection<BicepValue<T>> Values => _values.Values;

sdk/provisioning/Azure.Provisioning/src/BicepListOfT.cs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ public BicepValue<T> this[int index]
110110
}
111111
// the index is out of range, we put a value factory as the literal value of this bicep value
112112
// this would blow up when we try to compile it later, but it would be fine if we convert it to an expression
113-
var value = new BicepValue<T>(GetItemSelf(index), () => _values[index].Value);
114-
return value;
113+
return new BicepValue<T>(GetItemSelf(index), () => _values[index].Value);
115114
}
116115
}
117116
set
@@ -133,11 +132,8 @@ _self is not null
133132

134133
private void SetSelfForItem(BicepValue<T> item, int index)
135134
{
136-
if (_self is not null)
137-
{
138-
var itemSelf = GetItemSelf(index);
139-
item.SetSelf(itemSelf);
140-
}
135+
var itemSelf = GetItemSelf(index);
136+
item.SetSelf(itemSelf);
141137
}
142138

143139
private void RemoveSelfForItem(BicepValue<T> item)
@@ -188,12 +184,7 @@ public bool Remove(BicepValue<T> item)
188184
int index = _values.IndexOf(item);
189185
if (index >= 0)
190186
{
191-
RemoveSelfForItem(item);
192187
RemoveAt(index);
193-
for (int i = index; i < _values.Count; i++)
194-
{
195-
SetSelfForItem(_values[i], i);
196-
}
197188
return true;
198189
}
199190
return false;

sdk/provisioning/Azure.Provisioning/src/BicepValue.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,7 @@ private protected BicepValue(BicepValueReference? self, BicepExpression expressi
9191
public override string ToString() => Compile().ToString();
9292

9393
/// <inheritdoc />
94-
public BicepExpression Compile() => CompileCore();
95-
96-
private protected virtual BicepExpression CompileCore()
97-
=> BicepTypeMapping.ToBicep(this, Format);
94+
public BicepExpression Compile() => BicepTypeMapping.ToBicep(this, Format);
9895

9996
/// <inheritdoc />
10097
void IBicepValue.Assign(IBicepValue source) => Assign(source);

sdk/provisioning/Azure.Provisioning/src/Primitives/BicepValueReference.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ internal virtual BicepExpression GetReference(bool throwIfNoRoot = true)
4949
public override string ToString() => GetReference(throwIfNoRoot: false).ToString();
5050
}
5151

52-
internal class BicepListValueReference(ProvisionableConstruct construct, string propertyName, string[]? path, int index) : BicepValueReference(construct, propertyName, path)
52+
internal class BicepListValueReference(ProvisionableConstruct construct, string propertyName, string[]? path, int index)
53+
: BicepValueReference(construct, propertyName, path)
5354
{
5455
public int Index { get; } = index;
5556

@@ -58,3 +59,13 @@ internal override BicepExpression GetReference(bool throwIfNoRoot = true)
5859
return base.GetReference(throwIfNoRoot).Index(new IntLiteralExpression(Index));
5960
}
6061
}
62+
63+
internal class BicepDictionaryValueReference(ProvisionableConstruct construct, string propertyName, string[]? path, string key)
64+
: BicepValueReference(construct, propertyName, path)
65+
{
66+
public string Key { get; } = key;
67+
internal override BicepExpression GetReference(bool throwIfNoRoot = true)
68+
{
69+
return base.GetReference(throwIfNoRoot).Index(Key);
70+
}
71+
}

0 commit comments

Comments
 (0)