@@ -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
@@ -463,6 +470,8 @@ func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type), depth int) xsd.Type
463
470
t .Doc = "Must be at least " + strconv .Itoa (t .Restriction .MinLength ) + " items long"
464
471
return t
465
472
}
473
+
474
+ flattenedTypes [xsd .XMLName (t )] = t .Base
466
475
return t .Base
467
476
case * xsd.ComplexType :
468
477
// 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
478
487
t .Name .Local , xsd .XMLName (t .Base ))
479
488
switch b := t .Base .(type ) {
480
489
case xsd.Builtin :
490
+ flattenedTypes [xsd .XMLName (t )] = b
481
491
return b
482
492
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
484
496
}
485
497
}
486
498
}
487
499
// We can flatten a struct field if its type does not
488
500
// need additional methods for unmarshalling.
489
501
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 )
491
503
t .Elements [i ] = el
492
504
push (el .Type )
493
505
cfg .debugf ("element %s %T(%s): %v" , el .Name .Local , t ,
494
506
xsd .XMLName (t ).Local , xsd .XMLName (el .Type ))
495
507
}
496
508
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 )
498
510
t .Attributes [i ] = attr
499
511
push (attr .Type )
500
512
cfg .debugf ("attribute %s %T(%s): %v" , attr .Name .Local , t ,
501
513
xsd .XMLName (t ).Local , xsd .XMLName (attr .Type ))
502
514
}
503
515
504
- t .Base = cfg .flatten1 (t .Base , push , depth + 1 )
516
+ t .Base = cfg .flatten1 (t .Base , flattenedTypes , push , depth + 1 )
505
517
506
518
// We expand all complexTypes to merge all of the fields from
507
519
// their ancestors, so generated code has no dependencies
0 commit comments