public static (bool Result, string Message) WriteProperty(this Utf8JsonWriter writer, JsonProperty property, Dictionary <string, object> context, ARMFunctions functions, IInfrastructure infrastructure) { // https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-numeric#copyindex if ("copy".Equals(property.Name, StringComparison.OrdinalIgnoreCase)) { var copyProperty = property.Value; // this is for Variable and Property iteration if (copyProperty.ValueKind == JsonValueKind.Array) { foreach (var item in property.Value.EnumerateArray()) { Copy copy = null; try { copy = Copy.Parse(item, context, functions, infrastructure); } catch (Exception ex) { return(false, ex.Message); } using JsonDocument doc = JsonDocument.Parse(copy.Input); var copyindex = new Dictionary <string, int>() { { copy.Name, 0 } }; Dictionary <string, object> copyContext = new Dictionary <string, object> { { "copyindex", copyindex }, { "currentloopname", copy.Name } }; foreach (var k in context.Keys) { copyContext.Add(k, context[k]); } writer.WritePropertyName(copy.Name); writer.WriteStartArray(); for (int i = 0; i < copy.Count; i++) { copyindex[copy.Name] = i; writer.WriteElement(doc.RootElement, copyContext, functions, infrastructure); } writer.WriteEndArray(); if (copyContext.TryGetValue(ContextKeys.DEPENDSON, out object copyDependsOn)) { List <string> dependsOn; if (context.TryGetValue(ContextKeys.DEPENDSON, out object d)) { dependsOn = d as List <string>; } else { dependsOn = new List <string>(); context.Add(ContextKeys.DEPENDSON, dependsOn); } dependsOn.AddRange(copyDependsOn as List <string>); } if (copyContext.ContainsKey(ContextKeys.NEED_REEVALUATE)) { context.TryAdd(ContextKeys.NEED_REEVALUATE, true); } } } // this is for output else if (copyProperty.ValueKind == JsonValueKind.Object) { var input = copyProperty.GetProperty("input"); var countProperty = copyProperty.GetProperty("count"); int count; if (countProperty.ValueKind == JsonValueKind.Number) { count = countProperty.GetInt32(); } else if (countProperty.ValueKind == JsonValueKind.String) { count = (int)functions.Evaluate(countProperty.GetString(), context); } else { throw new Exception("the property of count has wrong error. It should be number or an function return a number"); } var name = Guid.NewGuid().ToString("N"); var copyindex = new Dictionary <string, int>() { { name, 0 } }; Dictionary <string, object> copyContext = new Dictionary <string, object> { { "copyindex", copyindex }, { "currentloopname", name } }; foreach (var k in context.Keys) { copyContext.Add(k, context[k]); } writer.WritePropertyName("value"); writer.WriteStartArray(); for (int i = 0; i < count; i++) { copyindex[name] = i; writer.WriteElement(input, copyContext, functions, infrastructure); } writer.WriteEndArray(); } else { throw new Exception("the structer of copy property is wrong"); } } else { writer.WritePropertyName(property.Name); writer.WriteElement(property.Value, context, functions, infrastructure); } return(true, string.Empty); }
public static void WriteElement(this Utf8JsonWriter writer, JsonElement element, Dictionary <string, object> context, ARMFunctions functions, IInfrastructure infrastructure) { switch (element.ValueKind) { case JsonValueKind.Undefined: case JsonValueKind.Number: case JsonValueKind.True: case JsonValueKind.False: case JsonValueKind.Null: element.WriteTo(writer); break; case JsonValueKind.Object: writer.WriteStartObject(); foreach (var p in element.EnumerateObject()) { writer.WriteProperty(p, context, functions, infrastructure); } writer.WriteEndObject(); break; case JsonValueKind.Array: writer.WriteStartArray(); foreach (var a in element.EnumerateArray()) { writer.WriteElement(a, context, functions, infrastructure); } writer.WriteEndArray(); break; case JsonValueKind.String: var r = functions.Evaluate(element.GetString(), context); if (r is JsonValue j) { j.RootElement.WriteTo(writer); } else if (r is bool b) { writer.WriteBooleanValue(b); } else if (r is string s) { writer.WriteStringValue(s); } else if (r is Int32 i) { writer.WriteNumberValue(i); } else if (r is FakeJsonValue) { writer.WriteStringValue("fakeString"); } else { writer.WriteNullValue(); } break; default: break; } }