Ejemplo n.º 1
0
func (cfg *Config) overrideWildcardType(t *xsd.ComplexType, base xsd.Type) *xsd.ComplexType {
	var elem xsd.Element
	var found bool
	var replaced bool
Loop:
	for x := xsd.Type(t); xsd.Base(x) != nil; x = xsd.Base(x) {
		c, ok := x.(*xsd.ComplexType)
		if !ok {
			cfg.logf("warning: soap-encoded array %s extends %T %s",
				xsd.XMLName(x).Local, base, xsd.XMLName(base).Local)
			return t
		}
		for _, v := range c.Elements {
			if v.Wildcard {
				elem = v
				found = true
				break Loop
			}
		}
	}
	if !found {
		cfg.logf("could not override wildcard type for %s; not found in type hierarchy", t.Name.Local)
		return t
	}
	cfg.debugf("overriding wildcard element of %s type from %s to %s",
		t.Name.Local, xsd.XMLName(elem.Type).Local, xsd.XMLName(base).Local)
	elem.Type = base
	for i, v := range t.Elements {
		if v.Wildcard {
			t.Elements[i] = elem
			replaced = true
		}
	}
	if !replaced {
		t.Elements = append(t.Elements, elem)
	}
	return t
}
Ejemplo n.º 2
0
// To reduce the size of the Go source generated, all intermediate types
// are "squashed"; every type should be based on a Builtin or another
// type that the user wants included in the Go source.
func (cfg *Config) flatten1(t xsd.Type, push func(xsd.Type)) xsd.Type {
	switch t := t.(type) {
	case *xsd.SimpleType:
		var (
			chain         []xsd.Type
			base, builtin xsd.Type
			ok            bool
		)
		// TODO: handle list/union types
		for base = xsd.Base(t); base != nil; base = xsd.Base(base) {
			if builtin, ok = base.(xsd.Builtin); ok {
				break
			}
			chain = append(chain, base)
		}
		for _, v := range chain {
			if v, ok := v.(*xsd.SimpleType); ok {
				v.Base = builtin
				push(v)
			}
		}
		t.Base = builtin
		return t
	case *xsd.ComplexType:
		// We can "unpack" a struct if it is extending a simple
		// or built-in type and we are ignoring all of its attributes.
		switch t.Base.(type) {
		case xsd.Builtin, *xsd.SimpleType:
			if b, ok := t.Base.(xsd.Builtin); ok && b == xsd.AnyType {
				break
			}
			attributes, _ := cfg.filterFields(t)
			if len(attributes) == 0 {
				cfg.debugf("complexType %s extends simpleType %s, but all attributes are filtered. unpacking.",
					t.Name.Local, xsd.XMLName(t.Base))
				switch b := t.Base.(type) {
				case xsd.Builtin:
					return b
				case *xsd.SimpleType:
					return cfg.flatten1(t.Base, push)
				}
			}
		}
		// We can flatten a struct field if its type does not
		// need additional methods for unmarshalling.
		for i, el := range t.Elements {
			el.Type = cfg.flatten1(el.Type, push)
			if b, ok := el.Type.(*xsd.SimpleType); ok {
				if !b.List && len(b.Union) == 0 {
					el.Type = xsd.Base(el.Type)
				}
			}
			t.Elements[i] = el
		}
		for i, attr := range t.Attributes {
			attr.Type = cfg.flatten1(attr.Type, push)
			if b, ok := attr.Type.(*xsd.SimpleType); ok {
				if !b.List && len(b.Union) == 0 {
					attr.Type = xsd.Base(attr.Type)
				}
			}
			t.Attributes[i] = attr
		}
		return t
	case xsd.Builtin:
		// There are a few built-ins that do not map directly to Go types.
		// for these, we will declare them in the Go source.
		switch t {
		case xsd.ENTITIES, xsd.IDREFS, xsd.NMTOKENS:
			push(t)
		case xsd.Base64Binary, xsd.HexBinary:
			push(t)
		case xsd.Date, xsd.Time, xsd.DateTime:
			push(t)
		case xsd.GDay, xsd.GMonth, xsd.GMonthDay, xsd.GYear, xsd.GYearMonth:
			push(t)
		}
		return t
	}
	panic(fmt.Sprintf("unexpected %T", t))
}