Skip to content

Commit f33d329

Browse files
vraut-pdgcm29h
authored andcommitted
Bugfix: Only flatten a type once
See PR for details droyo#88
1 parent 77bd8be commit f33d329

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
@@ -467,6 +474,8 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
467474
t.Doc = "Must be exactly " + strconv.Itoa(t.Restriction.Length) + " items long"
468475
return t
469476
}
477+
478+
flattenedTypes[xsd.XMLName(t)] = t.Base
470479
return t.Base
471480
case *xsd.ComplexType:
472481
// We can "unpack" a struct if it is extending a simple
@@ -482,30 +491,33 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
482491
t.Name.Local, xsd.XMLName(t.Base))
483492
switch b := t.Base.(type) {
484493
case xsd.Builtin:
494+
flattenedTypes[xsd.XMLName(t)] = b
485495
return b
486496
case *xsd.SimpleType:
487-
return cfg.flatten1(t.Base, push, depth+1)
497+
res := cfg.flatten1(t.Base, flattenedTypes, push, depth+1)
498+
flattenedTypes[xsd.XMLName(t)] = res
499+
return res
488500
}
489501
}
490502
}
491503
// We can flatten a struct field if its type does not
492504
// need additional methods for unmarshalling.
493505
for i, el := range t.Elements {
494-
el.Type = cfg.flatten1(el.Type, push, depth+1)
506+
el.Type = cfg.flatten1(el.Type, flattenedTypes, push, depth+1)
495507
t.Elements[i] = el
496508
push(el.Type)
497509
cfg.debugf("element %s %T(%s): %v", el.Name.Local, t,
498510
xsd.XMLName(t).Local, xsd.XMLName(el.Type))
499511
}
500512
for i, attr := range t.Attributes {
501-
attr.Type = cfg.flatten1(attr.Type, push, depth+1)
513+
attr.Type = cfg.flatten1(attr.Type, flattenedTypes, push, depth+1)
502514
t.Attributes[i] = attr
503515
push(attr.Type)
504516
cfg.debugf("attribute %s %T(%s): %v", attr.Name.Local, t,
505517
xsd.XMLName(t).Local, xsd.XMLName(attr.Type))
506518
}
507519

508-
t.Base = cfg.flatten1(t.Base, push, depth+1)
520+
t.Base = cfg.flatten1(t.Base, flattenedTypes, push, depth+1)
509521

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

0 commit comments

Comments
 (0)