@@ -110,7 +110,7 @@ func (c *Code) NameOf(name xml.Name) string {
110
110
return "NOTFOUND" + name .Local
111
111
}
112
112
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 ) {
114
114
case xsd.Builtin :
115
115
return c .NameOf (b .Name ())
116
116
}
@@ -371,6 +371,8 @@ func (cfg *Config) flatten(types map[xml.Name]xsd.Type) []xsd.Type {
371
371
push := func (t xsd.Type ) {
372
372
result = append (result , t )
373
373
}
374
+
375
+ var flattenedTypes = map [xml.Name ]xsd.Type {}
374
376
for _ , t := range types {
375
377
if xsd .XMLName (t ).Local == "_self" {
376
378
continue
@@ -384,7 +386,7 @@ func (cfg *Config) flatten(types map[xml.Name]xsd.Type) []xsd.Type {
384
386
continue
385
387
}
386
388
}
387
- if t := cfg .flatten1 (t , push , 0 ); t != nil {
389
+ if t := cfg .flatten1 (t , flattenedTypes , push , 0 ); t != nil {
388
390
push (t )
389
391
}
390
392
}
@@ -402,7 +404,12 @@ func dedup(types []xsd.Type) (unique []xsd.Type) {
402
404
return unique
403
405
}
404
406
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
+
406
413
const maxDepth = 1000
407
414
if depth > maxDepth {
408
415
return t
@@ -467,6 +474,8 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
467
474
t .Doc = "Must be exactly " + strconv .Itoa (t .Restriction .Length ) + " items long"
468
475
return t
469
476
}
477
+
478
+ flattenedTypes [xsd .XMLName (t )] = t .Base
470
479
return t .Base
471
480
case * xsd.ComplexType :
472
481
// 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
482
491
t .Name .Local , xsd .XMLName (t .Base ))
483
492
switch b := t .Base .(type ) {
484
493
case xsd.Builtin :
494
+ flattenedTypes [xsd .XMLName (t )] = b
485
495
return b
486
496
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
488
500
}
489
501
}
490
502
}
491
503
// We can flatten a struct field if its type does not
492
504
// need additional methods for unmarshalling.
493
505
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 )
495
507
t .Elements [i ] = el
496
508
push (el .Type )
497
509
cfg .debugf ("element %s %T(%s): %v" , el .Name .Local , t ,
498
510
xsd .XMLName (t ).Local , xsd .XMLName (el .Type ))
499
511
}
500
512
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 )
502
514
t .Attributes [i ] = attr
503
515
push (attr .Type )
504
516
cfg .debugf ("attribute %s %T(%s): %v" , attr .Name .Local , t ,
505
517
xsd .XMLName (t ).Local , xsd .XMLName (attr .Type ))
506
518
}
507
519
508
- t .Base = cfg .flatten1 (t .Base , push , depth + 1 )
520
+ t .Base = cfg .flatten1 (t .Base , flattenedTypes , push , depth + 1 )
509
521
510
522
// We expand all complexTypes to merge all of the fields from
511
523
// their ancestors, so generated code has no dependencies
0 commit comments