diff --git a/internal/codegen/parser/libvirtxml.go b/internal/codegen/parser/libvirtxml.go index 4fd32b905..66ca41d02 100644 --- a/internal/codegen/parser/libvirtxml.go +++ b/internal/codegen/parser/libvirtxml.go @@ -85,6 +85,17 @@ func (r *LibvirtXMLReflector) ReflectStruct(structType reflect.Type) (*generator continue } + if field.Anonymous { + if field.Type.Kind() == reflect.Struct { + embeddedIR, err := r.ReflectStruct(field.Type) + if err != nil { + return nil, fmt.Errorf("analyzing embedded struct %s: %w", field.Type.Name(), err) + } + ir.Fields = append(ir.Fields, embeddedIR.Fields...) + } + continue + } + fieldIR, err := r.analyzeField(typeName, field) if err != nil { return nil, fmt.Errorf("analyzing field %s: %w", field.Name, err) @@ -248,11 +259,6 @@ func (r *LibvirtXMLReflector) analyzeField(structName string, field reflect.Stru return nil, nil } - // Skip embedded/anonymous fields - if field.Anonymous { - return nil, nil - } - xmlTag := field.Tag.Get("xml") if xmlTag == "" { // Skip fields without XML tags diff --git a/internal/codegen/parser/libvirtxml_test.go b/internal/codegen/parser/libvirtxml_test.go new file mode 100644 index 000000000..2b72cf2d4 --- /dev/null +++ b/internal/codegen/parser/libvirtxml_test.go @@ -0,0 +1,40 @@ +package parser + +import ( + "reflect" + "slices" + "testing" + + "libvirt.org/go/libvirtxml" +) + +func TestReflectStruct_AnonymousEmbeddedFields(t *testing.T) { + reflector := NewLibvirtXMLReflector() + + ir, err := reflector.ReflectStruct(reflect.TypeOf(libvirtxml.DomainFeatureHyperVSpinlocks{})) + if err != nil { + t.Fatalf("ReflectStruct() error = %v", err) + } + + fields := make(map[string]bool, len(ir.Fields)) + for _, field := range ir.Fields { + fields[field.TFName] = true + } + + if !fields["state"] { + t.Fatalf("expected embedded field %q to be reflected, got fields %v", "state", keys(fields)) + } + + if !fields["retries"] { + t.Fatalf("expected field %q to be reflected, got fields %v", "retries", keys(fields)) + } +} + +func keys(fields map[string]bool) []string { + names := make([]string, 0, len(fields)) + for name := range fields { + names = append(names, name) + } + slices.Sort(names) + return names +}