private static void GenerateTerraform()

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);
    }