in src/TemplateRefGenerator/Generators/CodeSampleGenerator.cs [324:443]
private static void GenerateTerraform(MarkdownGenerator.ResourceMetadata resource, StringBuilder sb, int indentLevel, TypeBase type, string? path, HashSet<TypeBase> visited)
{
if (visited.Contains(type))
{
// to avoid infinite recursion, exit early
sb.Append($"...");
return;
}
visited.Add(type);
var indent = GetIndent(indentLevel);
var propIndent = GetIndent(indentLevel + 1);
void AddProperty(string name, Action writeValue)
{
sb.Append($"{propIndent}{name} = ");
writeValue();
sb.AppendLine();
}
switch (type)
{
case ResourceType resourceType:
sb.Append($"resource \"azapi_resource\" \"symbolicname\" ");
GenerateTerraform(resource, sb, 0, resourceType.Body.Type, "", visited);
break;
case ObjectType objectType:
var props = MarkdownGenerator.GetOrderedWritableProperties(objectType.Properties).ToList();
var additionalPropType = objectType.AdditionalProperties;
sb.AppendLine("{");
if (path == "")
{
if (props.FirstOrDefault(x => x.Key == "name") is {} nameProp)
{
props.Remove(nameProp);
}
AddProperty("type", () => sb.Append($"\"{resource.ResourceType}@{resource.ApiVersion}\""));
AddProperty("name", () => sb.Append($"\"string\""));
AddProperty("parent_id", () => sb.Append($"\"string\""));
if (props.FirstOrDefault(x => x.Key == "identity") is {} identityProp && identityProp.Key != null)
{
props.Remove(identityProp);
sb.AppendLine($"{propIndent}identity {{");
var nestedPropIndent = GetIndent(indentLevel + 2);
sb.AppendLine($"{nestedPropIndent}type = \"string\"");
sb.AppendLine($"{nestedPropIndent}identity_ids = [");
sb.AppendLine($"{nestedPropIndent}{GetIndent(1)}\"string\"");
sb.AppendLine($"{nestedPropIndent}]");
sb.AppendLine($"{propIndent}}}");
}
}
var bodyProps = props.Where(x => path == "" && !TerraformRootProperties.Contains(x.Key)).ToList();
foreach (var (name, prop) in props.Except(bodyProps))
{
AddProperty(name, () => GenerateTerraform(resource, sb, indentLevel + 1, prop.Type.Type, $"{path}.{name}", visited));
}
if (bodyProps.Any())
{
AddProperty("body", () => {
sb.AppendLine("{");
foreach (var (name, prop) in bodyProps)
{
AddProperty($" {name}", () => GenerateTerraform(resource, sb, indentLevel + 2, prop.Type.Type, $"{path}.{name}", visited));
}
sb.Append($"{propIndent}}}");
});
}
if (!props.Any() && additionalPropType is {})
{
AddProperty("{customized property}", () => GenerateTerraform(resource, sb, indentLevel + 1, additionalPropType.Type, $"{path}.*", visited));
}
sb.Append(indent + "}");
break;
case ArrayType arrayType:
sb.AppendLine("[");
sb.Append(propIndent);
GenerateTerraform(resource, sb, indentLevel + 1, arrayType.ItemType.Type, $"{path}[*]", visited);
sb.AppendLine();
sb.Append(indent + "]");
break;
case StringLiteralType stringLiteralType:
sb.Append($"\"{stringLiteralType.Value}\"");
break;
case IntegerType:
sb.Append($"int");
break;
case BooleanType:
sb.Append($"bool");
break;
case StringType:
case UnionType:
sb.Append($"\"string\"");
break;
case DiscriminatedObjectType objectType:
sb.AppendLine("{");
foreach (var (name, prop) in MarkdownGenerator.GetOrderedWritableProperties(objectType.BaseProperties))
{
AddProperty(name, () => GenerateTerraform(resource, sb, indentLevel + 1, prop.Type.Type, $"{path}.{name}", visited));
}
AddProperty(objectType.Discriminator, () => sb.Append($"\"string\""));
sb.AppendLine($"{propIndent}// For remaining properties, see {objectType.Name} objects");
sb.Append(indent + "}");
break;
default:
sb.Append($"?");
break;
}
visited.Remove(type);
}