Skip to content

Commit 4ba7047

Browse files
committed
Bugfix: Only flatten a type once
See PR for details droyo#88
1 parent 9e53177 commit 4ba7047

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

xsdgen/xsdgen.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (c *Code) NameOf(name xml.Name) string {
110110
return "NOTFOUND" + name.Local
111111
}
112112

113-
switch b := c.cfg.flatten1(t, func(xsd.Type) {}, 0).(type) {
113+
switch b := c.cfg.flatten1(t, map[xml.Name]xsd.Type{}, func(xsd.Type) {}, 0).(type) {
114114
case xsd.Builtin:
115115
return c.NameOf(b.Name())
116116
}
@@ -371,6 +371,8 @@ func (cfg *Config) flatten(types map[xml.Name]xsd.Type) []xsd.Type {
371371
push := func(t xsd.Type) {
372372
result = append(result, t)
373373
}
374+
375+
var flattenedTypes = map[xml.Name]xsd.Type{}
374376
for _, t := range types {
375377
if xsd.XMLName(t).Local == "_self" {
376378
continue
@@ -384,7 +386,7 @@ func (cfg *Config) flatten(types map[xml.Name]xsd.Type) []xsd.Type {
384386
continue
385387
}
386388
}
387-
if t := cfg.flatten1(t, push, 0); t != nil {
389+
if t := cfg.flatten1(t, flattenedTypes, push, 0); t != nil {
388390
push(t)
389391
}
390392
}
@@ -402,7 +404,12 @@ func dedup(types []xsd.Type) (unique []xsd.Type) {
402404
return unique
403405
}
404406

405-
func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type {
407+
func (cfg *Config) flatten1(t xsd.Type, flattenedTypes map[xml.Name]xsd.Type, push func(xsd.Type), depth int) xsd.Type {
408+
if res, ok := flattenedTypes[xsd.XMLName(t)]; ok {
409+
return res
410+
}
411+
flattenedTypes[xsd.XMLName(t)] = t
412+
406413
const maxDepth = 1000
407414
if depth > maxDepth {
408415
return t
@@ -463,6 +470,8 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
463470
t.Doc = "Must be at least " + strconv.Itoa(t.Restriction.MinLength) + " items long"
464471
return t
465472
}
473+
474+
flattenedTypes[xsd.XMLName(t)] = t.Base
466475
return t.Base
467476
case *xsd.ComplexType:
468477
// We can "unpack" a struct if it is extending a simple
@@ -478,30 +487,33 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
478487
t.Name.Local, xsd.XMLName(t.Base))
479488
switch b := t.Base.(type) {
480489
case xsd.Builtin:
490+
flattenedTypes[xsd.XMLName(t)] = b
481491
return b
482492
case *xsd.SimpleType:
483-
return cfg.flatten1(t.Base, push, depth+1)
493+
res := cfg.flatten1(t.Base, flattenedTypes, push, depth+1)
494+
flattenedTypes[xsd.XMLName(t)] = res
495+
return res
484496
}
485497
}
486498
}
487499
// We can flatten a struct field if its type does not
488500
// need additional methods for unmarshalling.
489501
for i, el := range t.Elements {
490-
el.Type = cfg.flatten1(el.Type, push, depth+1)
502+
el.Type = cfg.flatten1(el.Type, flattenedTypes, push, depth+1)
491503
t.Elements[i] = el
492504
push(el.Type)
493505
cfg.debugf("element %s %T(%s): %v", el.Name.Local, t,
494506
xsd.XMLName(t).Local, xsd.XMLName(el.Type))
495507
}
496508
for i, attr := range t.Attributes {
497-
attr.Type = cfg.flatten1(attr.Type, push, depth+1)
509+
attr.Type = cfg.flatten1(attr.Type, flattenedTypes, push, depth+1)
498510
t.Attributes[i] = attr
499511
push(attr.Type)
500512
cfg.debugf("attribute %s %T(%s): %v", attr.Name.Local, t,
501513
xsd.XMLName(t).Local, xsd.XMLName(attr.Type))
502514
}
503515

504-
t.Base = cfg.flatten1(t.Base, push, depth+1)
516+
t.Base = cfg.flatten1(t.Base, flattenedTypes, push, depth+1)
505517

506518
// We expand all complexTypes to merge all of the fields from
507519
// their ancestors, so generated code has no dependencies

0 commit comments

Comments
 (0)