private TypeMapping ImportTypeMapping(TypeModel model, string ns, ImportContext context, string dataType, XmlAttributes a, bool repeats, bool openModel, RecursionLimiter limiter)
{
try
{
if (dataType.Length > 0)
{
TypeDesc modelTypeDesc = TypeScope.IsOptionalValue(model.Type) ? model.TypeDesc.BaseTypeDesc : model.TypeDesc;
if (!modelTypeDesc.IsPrimitive)
{
throw new InvalidOperationException(SR.Format(SR.XmlInvalidDataTypeUsage, dataType, "XmlElementAttribute.DataType"));
}
TypeDesc td = _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace);
if (td == null)
{
throw new InvalidOperationException(SR.Format(SR.XmlInvalidXsdDataType, dataType, "XmlElementAttribute.DataType", new XmlQualifiedName(dataType, XmlSchema.Namespace).ToString()));
}
if (modelTypeDesc.FullName != td.FullName)
{
throw new InvalidOperationException(SR.Format(SR.XmlDataTypeMismatch, dataType, "XmlElementAttribute.DataType", modelTypeDesc.FullName));
}
}
if (a == null)
a = GetAttributes(model.Type, false);
if ((a.XmlFlags & ~(XmlAttributeFlags.Type | XmlAttributeFlags.Root)) != 0)
throw new InvalidOperationException(SR.Format(SR.XmlInvalidTypeAttributes, model.Type.FullName));
switch (model.TypeDesc.Kind)
{
case TypeKind.Enum:
return ImportEnumMapping((EnumModel)model, ns, repeats);
case TypeKind.Primitive:
if (a.XmlFlags != 0) throw InvalidAttributeUseException(model.Type);
return ImportPrimitiveMapping((PrimitiveModel)model, context, dataType, repeats);
case TypeKind.Array:
case TypeKind.Collection:
case TypeKind.Enumerable:
//if (a.XmlFlags != 0) throw InvalidAttributeUseException(model.Type);
if (context != ImportContext.Element) throw UnsupportedException(model.TypeDesc, context);
_arrayNestingLevel++;
ArrayMapping arrayMapping = ImportArrayLikeMapping((ArrayModel)model, ns, limiter);
_arrayNestingLevel--;
return arrayMapping;
case TypeKind.Root:
case TypeKind.Class:
case TypeKind.Struct:
if (context != ImportContext.Element) throw UnsupportedException(model.TypeDesc, context);
if (model.TypeDesc.IsOptionalValue)
{
TypeDesc valueTypeDesc = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc : _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace);
string xsdTypeName = valueTypeDesc.DataType == null ? valueTypeDesc.Name : valueTypeDesc.DataType.Name;
TypeMapping baseMapping = GetTypeMapping(xsdTypeName, ns, valueTypeDesc, _types, null);
if (baseMapping == null)
baseMapping = ImportTypeMapping(_modelScope.GetTypeModel(model.TypeDesc.BaseTypeDesc.Type), ns, context, dataType, null, repeats, openModel, limiter);
return CreateNullableMapping(baseMapping, model.TypeDesc.Type);
}
else
{
return ImportStructLikeMapping((StructModel)model, ns, openModel, a, limiter);
}
default:
if (model.TypeDesc.Kind == TypeKind.Serializable)
{
// We allow XmlRoot attribute on IXmlSerializable, but not others
if ((a.XmlFlags & ~XmlAttributeFlags.Root) != 0)
{
throw new InvalidOperationException(SR.Format(SR.XmlSerializableAttributes, model.TypeDesc.FullName, typeof(XmlSchemaProviderAttribute).Name));
}
}
else
{
if (a.XmlFlags != 0) throw InvalidAttributeUseException(model.Type);
}
if (model.TypeDesc.IsSpecial)
return ImportSpecialMapping(model.Type, model.TypeDesc, ns, context, limiter);
throw UnsupportedException(model.TypeDesc, context);
}
}
catch (Exception e)
{
if (e is OutOfMemoryException)
{
throw;
}
throw CreateTypeReflectionException(model.TypeDesc.FullName, e);
}
}