internal TypeModel GetTypeModel(Type type, bool directReference) { TypeModel model = (TypeModel)_models[type]; if (model != null) { return(model); } TypeDesc typeDesc = _typeScope.GetTypeDesc(type, null, directReference); switch (typeDesc.Kind) { case TypeKind.Enum: model = new EnumModel(type, typeDesc, this); break; case TypeKind.Primitive: model = new PrimitiveModel(type, typeDesc, this); break; case TypeKind.Array: case TypeKind.Collection: case TypeKind.Enumerable: model = new ArrayModel(type, typeDesc, this); break; case TypeKind.Root: case TypeKind.Class: case TypeKind.Struct: model = new StructModel(type, typeDesc, this); break; default: if (!typeDesc.IsSpecial) { throw new NotSupportedException(string.Format(ResXml.XmlUnsupportedTypeKind, type.FullName)); } model = new SpecialModel(type, typeDesc, this); break; } _models.Add(type, model); return(model); }
private TypeMapping ImportTypeMapping(TypeModel model, string dataType, RecursionLimiter limiter) { if (dataType.Length > 0) { if (!model.TypeDesc.IsPrimitive) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidDataTypeUsage, dataType, "SoapElementAttribute.DataType")); } TypeDesc td = _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); if (td == null) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidXsdDataType, dataType, "SoapElementAttribute.DataType", new XmlQualifiedName(dataType, XmlSchema.Namespace).ToString())); } if (model.TypeDesc.FullName != td.FullName) { throw new InvalidOperationException(SR.Format(SR.XmlDataTypeMismatch, dataType, "SoapElementAttribute.DataType", model.TypeDesc.FullName)); } } SoapAttributes a = GetAttributes(model.Type); if ((a.GetSoapFlags() & ~SoapAttributeFlags.Type) != 0) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidTypeAttributes, model.Type.FullName)); } switch (model.TypeDesc.Kind) { case TypeKind.Enum: return(ImportEnumMapping((EnumModel)model)); case TypeKind.Primitive: return(ImportPrimitiveMapping((PrimitiveModel)model, dataType)); case TypeKind.Array: case TypeKind.Collection: case TypeKind.Enumerable: return(ImportArrayLikeMapping((ArrayModel)model, limiter)); case TypeKind.Root: case TypeKind.Class: case TypeKind.Struct: if (model.TypeDesc.IsOptionalValue) { TypeDesc baseTypeDesc = model.TypeDesc.BaseTypeDesc; SoapAttributes baseAttributes = GetAttributes(baseTypeDesc.Type); string typeNs = _defaultNs; if (baseAttributes.SoapType != null && baseAttributes.SoapType.Namespace != null) { typeNs = baseAttributes.SoapType.Namespace; } TypeDesc valueTypeDesc = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc : _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace); string xsdTypeName = string.IsNullOrEmpty(dataType) ? model.TypeDesc.BaseTypeDesc.Name : dataType; TypeMapping baseMapping = GetTypeMapping(xsdTypeName, typeNs, valueTypeDesc); if (baseMapping == null) { baseMapping = ImportTypeMapping(_modelScope.GetTypeModel(baseTypeDesc.Type), dataType, limiter); } return(CreateNullableMapping(baseMapping, model.TypeDesc.Type)); } else { return(ImportStructLikeMapping((StructModel)model, limiter)); } default: throw new NotSupportedException(SR.Format(SR.XmlUnsupportedSoapTypeKind, model.TypeDesc.FullName)); } }