You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: internal/codegen/README.md
+43Lines changed: 43 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,7 @@ The generator follows the global XML <-> HCL mapping rules in `docs/schema-mappi
16
16
17
17
- Inputs: libvirtxml reflection, docs registry (`internal/codegen/docs/*.yaml` from docindex/docgen), small config hooks
18
18
- IR builder: normalizes struct metadata, tracks optionality, and carries doc strings
19
+
- Field policy layer: applies Terraform-specific semantics after reflection (for example top-level identities, immutability, and exact path overrides)
19
20
- Generators: templates render models/schemas/converters into `internal/generated/*.gen.go`
20
21
- Orchestration: `main.go` wires the pieces and runs gofmt
21
22
@@ -53,6 +54,48 @@ The generator follows the global XML <-> HCL mapping rules in `docs/schema-mappi
53
54
54
55
- Resources embed the generated models/schemas and call the conversions; add/override resource-specific fields (IDs, create helpers) manually
55
56
57
+
## Field Policy Design
58
+
59
+
The generator has two separate responsibilities:
60
+
61
+
1. Structural analysis: reflect libvirtxml structs into IR using facts from Go types and, over time, RNG metadata. This layer should answer questions like "is this a pointer?", "is this an XML attribute?", and "is this nested or repeated?".
62
+
2. Terraform policy: decide how those reflected fields behave in Terraform schemas and conversions. This layer owns decisions like `Computed`, `Required`, `RequiresReplace`, and "preserve user intent" behavior.
63
+
64
+
Keep those layers separate. The parser should not accumulate ad hoc Terraform exceptions based on struct names. If a field needs special Terraform behavior, prefer a policy rule after reflection rather than embedding one-off conditionals into the reflector.
65
+
66
+
### Policy rules
67
+
68
+
Policy should be applied in an ordered pass over `StructIR` / `FieldIR`:
69
+
70
+
- Generic scope-aware rules first
71
+
- Exact path overrides second
72
+
- Resource-specific fallbacks last
73
+
74
+
Examples:
75
+
76
+
- Top-level resource identity fields such as `id`, `uuid`, and `key` are provider-managed and should usually be `Computed`
77
+
- Top-level `name` and some top-level `type` fields are immutable inputs and should usually be `Required` plus `RequiresReplace`
78
+
- Nested `id` fields are not automatically provider-managed; many are part of libvirt configuration and should keep their reflected semantics unless an explicit override says otherwise
79
+
- Reported-only fields such as storage pool `capacity` / `allocation` / `available` should be handled by explicit policy rules, not inferred from field names alone
80
+
81
+
### Override strategy
82
+
83
+
When the default rules are not enough, use explicit overrides keyed by full Terraform or XML path rather than helper functions like `isUserManagedFooStruct`.
84
+
85
+
Good override targets:
86
+
87
+
-`storage_pool.capacity`
88
+
-`storage_pool.allocation`
89
+
-`storage_volume.physical`
90
+
91
+
Avoid:
92
+
93
+
- Struct-name allowlists for one field
94
+
- Field-name heuristics that ignore nesting scope
95
+
- Mixing reflection logic with provider semantics in the same function
96
+
97
+
This keeps the generator predictable, makes exceptions easy to audit, and prevents the parser from turning into a collection of special cases.
98
+
56
99
## Documentation tools
57
100
58
101
-`cmd/docindex`: scrape `/usr/share/doc/libvirt/html` into an index used for prompting. Run `go run ./internal/codegen/cmd/docindex --input /usr/share/doc/libvirt/html --output internal/codegen/docs/.index.json`.
0 commit comments