Skip to content

Commit bff95a7

Browse files
committed
refactor(codegen): Split large files in pkg/translate/ for improved maintainability
Split three oversized files into 17 focused modules to improve code organization and maintainability. This is a pure refactoring with zero behavioral changes, verified by test-harness showing identical generated code. Changes: - Split terraform_provider/funcs.go (3,428 lines) → 9 files: * encryption.go - Encrypted value handling * conversion.go - Terraform/Pango data conversion * location.go - Location struct and schema generation * schema.go - Terraform schema generation * import_state.go - Import state handling * structs_model.go - Terraform model struct generation * crud_operations.go - CRUD operations (Create/Read/Update/Delete) * ephemeral_operations.go - Ephemeral resource operations * utils.go - Shared utilities - Split structs.go (1,029 lines) → 5 files: * template_utils.go - Template loading utilities * import_location.go - Import and location rendering * type_calculation.go - Type and tag calculation * struct_generation.go - Struct creation and rendering * xml_marshaling.go - XML marshaling and containers - Split terraform_provider/terraform_provider_file.go (713 lines) → 3 files: * generator.go - Core generator orchestration * entity_generators.go - Entity-specific generation * provider_generators.go - Provider-level generation Metrics: - Largest file reduced from 3,428 to 471 lines (86% reduction) - All files now under 750 lines - Average file size: ~250 lines - Zero files over 500 lines (previously 3) Verification: - All tests pass (make test/codegen) - Generated code identical to baseline (codegen-diff) - No circular dependencies - No compilation errors This refactoring improves code navigability, makes reviews easier, and reduces cognitive load by organizing code into single-responsibility modules.
1 parent a9a2d78 commit bff95a7

19 files changed

Lines changed: 4942 additions & 4726 deletions

pkg/translate/import_location.go

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package translate
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"strings"
7+
"text/template"
8+
9+
"github.com/paloaltonetworks/pan-os-codegen/pkg/properties"
10+
)
11+
12+
// LocationType function used in template location.tmpl to generate location type name.
13+
func LocationType(location *properties.Location, pointer bool) string {
14+
prefix := ""
15+
if pointer {
16+
prefix = "*"
17+
}
18+
return fmt.Sprintf("%s%sLocation", prefix, location.Name.CamelCase)
19+
}
20+
21+
type importXpathVariableSpec struct {
22+
Name *properties.NameVariant
23+
Description string
24+
Default *string
25+
}
26+
27+
type importLocationSpec struct {
28+
Name *properties.NameVariant
29+
XpathElements []string
30+
XpathVariables []importXpathVariableSpec
31+
XpathFinalElement string
32+
ResponseXpath string
33+
}
34+
35+
type importSpec struct {
36+
Variant *properties.NameVariant
37+
Type *properties.NameVariant
38+
Locations []importLocationSpec
39+
}
40+
41+
func createImportLocationSpecsForLocation(location properties.ImportLocation) importLocationSpec {
42+
var variables []importXpathVariableSpec
43+
variablesByName := make(map[string]importXpathVariableSpec, len(location.XpathVariables))
44+
45+
for _, elt := range location.OrderedXpathVariables() {
46+
var defaultValue *string
47+
if elt.Default != "" {
48+
defaultValue = &elt.Default
49+
}
50+
variableSpec := importXpathVariableSpec{
51+
Name: elt.Name,
52+
Description: elt.Description,
53+
Default: defaultValue,
54+
}
55+
56+
variables = append(variables, variableSpec)
57+
variablesByName[elt.Name.Underscore] = variableSpec
58+
}
59+
60+
var elements []string
61+
for _, elt := range location.XpathElements {
62+
if strings.HasPrefix(elt, "$") {
63+
variableName := elt[1:]
64+
asEntryXpath := fmt.Sprintf("util.AsEntryXpath(o.%s)", variablesByName[variableName].Name.LowerCamelCase)
65+
elements = append(elements, asEntryXpath)
66+
} else {
67+
elements = append(elements, fmt.Sprintf("\"%s\"", elt))
68+
}
69+
}
70+
71+
xpathFinalElement := location.XpathElements[len(location.XpathElements)-1]
72+
responseXpath := fmt.Sprintf("result>%s>member", xpathFinalElement)
73+
74+
return importLocationSpec{
75+
Name: location.Name,
76+
XpathElements: elements,
77+
XpathVariables: variables,
78+
XpathFinalElement: xpathFinalElement,
79+
ResponseXpath: responseXpath,
80+
}
81+
}
82+
83+
func createImportSpecsForNormalization(spec *properties.Normalization) []importSpec {
84+
var specs []importSpec
85+
86+
for _, imp := range spec.Imports {
87+
var locations []importLocationSpec
88+
for _, location := range imp.OrderedLocations() {
89+
locations = append(locations, createImportLocationSpecsForLocation(*location))
90+
}
91+
92+
specs = append(specs, importSpec{
93+
Variant: imp.Variant,
94+
Type: imp.Type,
95+
Locations: locations,
96+
})
97+
}
98+
99+
return specs
100+
}
101+
102+
// RenderEntryImportStructs generates import location structs for a normalization spec.
103+
func RenderEntryImportStructs(spec *properties.Normalization) (string, error) {
104+
type renderContext struct {
105+
Specs []importSpec
106+
}
107+
108+
tmplContent, err := loadTemplate("partials/import_location_struct.tmpl")
109+
if err != nil {
110+
return "", err
111+
}
112+
113+
tmpl, err := template.New("render-entry-import-structs").Parse(tmplContent)
114+
if err != nil {
115+
return "", err
116+
}
117+
118+
data := renderContext{
119+
Specs: createImportSpecsForNormalization(spec),
120+
}
121+
122+
var buf bytes.Buffer
123+
err = tmpl.Execute(&buf, data)
124+
if err != nil {
125+
return "", err
126+
}
127+
128+
return buf.String(), nil
129+
}
130+
131+
type locationVariableSpec struct {
132+
Name *properties.NameVariant
133+
LocationFilter bool
134+
}
135+
136+
type locationSpec struct {
137+
Name *properties.NameVariant
138+
Variables []locationVariableSpec
139+
HasFilter bool
140+
}
141+
142+
func createLocationVariableSpecForLocation(loc *properties.Location) []locationVariableSpec {
143+
var variables []locationVariableSpec
144+
145+
for _, elt := range loc.OrderedVars() {
146+
variables = append(variables, locationVariableSpec{
147+
Name: elt.Name,
148+
LocationFilter: elt.LocationFilter,
149+
})
150+
}
151+
152+
return variables
153+
}
154+
155+
func createLocationSpecForNormalization(spec *properties.Normalization) []locationSpec {
156+
var locations []locationSpec
157+
for _, elt := range spec.OrderedLocations() {
158+
locations = append(locations, locationSpec{
159+
Name: elt.Name,
160+
HasFilter: elt.HasFilter(),
161+
Variables: createLocationVariableSpecForLocation(elt),
162+
})
163+
}
164+
165+
return locations
166+
}
167+
168+
// RenderLocationFilter generates location filter structs for a normalization spec.
169+
func RenderLocationFilter(spec *properties.Normalization) (string, error) {
170+
type renderContext struct {
171+
Specs []locationSpec
172+
}
173+
174+
tmplContent, err := loadTemplate("partials/location_filter.tmpl")
175+
if err != nil {
176+
return "", err
177+
}
178+
179+
tmpl, err := template.New("render-entry-import-structs").Parse(tmplContent)
180+
if err != nil {
181+
return "", err
182+
}
183+
184+
data := renderContext{
185+
Specs: createLocationSpecForNormalization(spec),
186+
}
187+
188+
var buf bytes.Buffer
189+
err = tmpl.Execute(&buf, data)
190+
if err != nil {
191+
return "", err
192+
}
193+
194+
return buf.String(), nil
195+
}

0 commit comments

Comments
 (0)