private MemberMapping ImportFieldMapping(FieldModel model, SoapAttributes a, string ns, RecursionLimiter limiter)
        {
            if (a.SoapIgnore)
            {
                return(null);
            }
            MemberMapping member = new MemberMapping();

            member.IsSoap                       = true;
            member.Name                         = model.Name;
            member.CheckShouldPersist           = model.CheckShouldPersist;
            member.CheckSpecified               = model.CheckSpecified;
            member.MemberInfo                   = model.MemberInfo;
            member.CheckSpecifiedMemberInfo     = model.CheckSpecifiedMemberInfo;
            member.CheckShouldPersistMethodInfo = model.CheckShouldPersistMethodInfo;
            member.ReadOnly                     = model.ReadOnly; // || !model.FieldTypeDesc.HasDefaultConstructor;
            ImportAccessorMapping(member, model, a, ns, XmlSchemaForm.Unqualified, limiter);
            return(member);
        }
        private EnumMapping ImportEnumMapping(EnumModel model)
        {
            SoapAttributes a      = GetAttributes(model.Type);
            string         typeNs = _defaultNs;

            if (a.SoapType != null && a.SoapType.Namespace != null)
            {
                typeNs = a.SoapType.Namespace;
            }
            string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name);

            typeName = XmlConvert.EncodeLocalName(typeName);

            EnumMapping mapping = (EnumMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);

            if (mapping == null)
            {
                mapping           = new EnumMapping();
                mapping.IsSoap    = true;
                mapping.TypeDesc  = model.TypeDesc;
                mapping.TypeName  = typeName;
                mapping.Namespace = typeNs;
                mapping.IsFlags   = model.Type.GetTypeInfo().IsDefined(typeof(FlagsAttribute), false);
                _typeScope.AddTypeMapping(mapping);
                _types.Add(typeName, typeNs, mapping);
                ArrayList constants = new ArrayList();
                for (int i = 0; i < model.Constants.Length; i++)
                {
                    ConstantMapping constant = ImportConstantMapping(model.Constants[i]);
                    if (constant != null)
                    {
                        constants.Add(constant);
                    }
                }
                if (constants.Count == 0)
                {
                    throw new InvalidOperationException(string.Format(ResXml.XmlNoSerializableMembers, model.TypeDesc.FullName));
                }
                mapping.Constants = (ConstantMapping[])constants.ToArray(typeof(ConstantMapping));
            }
            return(mapping);
        }
        private ConstantMapping ImportConstantMapping(ConstantModel model)
        {
            SoapAttributes a = GetAttributes(model.FieldInfo);

            if (a.SoapIgnore)
            {
                return(null);
            }
            if ((a.SoapFlags & ~SoapAttributeFlags.Enum) != 0)
            {
                throw new InvalidOperationException(ResXml.XmlInvalidEnumAttribute);
            }
            if (a.SoapEnum == null)
            {
                a.SoapEnum = new SoapEnumAttribute();
            }

            ConstantMapping constant = new ConstantMapping();

            constant.XmlName = a.SoapEnum.Name.Length == 0 ? model.Name : a.SoapEnum.Name;
            constant.Name    = model.Name;
            constant.Value   = model.Value;
            return(constant);
        }
 /// <include file='doc\SoapAttributeOverrides.uex' path='docs/doc[@for="SoapAttributeOverrides.Add"]/*' />
 /// <devdoc>
 ///    <para>[To be supplied.]</para>
 /// </devdoc>
 public void Add(Type type, SoapAttributes attributes)
 {
     Add(type, string.Empty, attributes);
 }
        private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter)
        {
            if (mapping.IsFullyInitialized)
            {
                return(true);
            }
            if (model.TypeDesc.BaseTypeDesc != null)
            {
                StructMapping baseMapping = ImportStructLikeMapping((StructModel)_modelScope.GetTypeModel(model.Type.GetTypeInfo().BaseType, false), limiter);

                // check to see if the import of the baseMapping was deffered
                int baseIndex = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping);
                if (baseIndex < 0)
                {
                    mapping.BaseMapping = baseMapping;
                }
                else
                {
                    // the import of the baseMapping was deffered, make sure that the derived mappings is deffered as well
                    if (!limiter.DeferredWorkItems.Contains(mapping))
                    {
                        limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    }
                    // make sure that baseMapping get processed before the derived
                    int top = limiter.DeferredWorkItems.Count - 1;
                    if (baseIndex < top)
                    {
                        ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex];
                        limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top];
                        limiter.DeferredWorkItems[top]       = baseMappingWorkItem;
                    }
                    return(false);
                }
            }
            ArrayList members = new ArrayList();

            foreach (MemberInfo memberInfo in model.GetMemberInfos())
            {
                if (memberInfo is FieldInfo || memberInfo is PropertyInfo)
                {
                    continue;
                }
                SoapAttributes memberAttrs = GetAttributes(memberInfo);
                if (memberAttrs.SoapIgnore)
                {
                    continue;
                }
                FieldModel fieldModel = model.GetFieldModel(memberInfo);
                if (fieldModel == null)
                {
                    continue;
                }
                MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace, limiter);
                if (member == null)
                {
                    continue;
                }

                if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue)
                {
                    if (model.TypeDesc.IsValueType)
                    {
                        throw new NotSupportedException(string.Format(ResXml.XmlRpcRefsInValueType, model.TypeDesc.FullName));
                    }
                    if (member.TypeDesc.IsValueType)
                    {
                        throw new NotSupportedException(string.Format(ResXml.XmlRpcNestedValueType, member.TypeDesc.FullName));
                    }
                }
                if (mapping.BaseMapping != null)
                {
                    if (mapping.BaseMapping.Declares(member, mapping.TypeName))
                    {
                        continue;
                    }
                }
                members.Add(member);
            }
            mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));
            if (mapping.BaseMapping == null)
            {
                mapping.BaseMapping = GetRootMapping();
            }
            IncludeTypes(model.Type, limiter);

            return(true);
        }
        private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter)
        {
            if (model.TypeDesc.Kind == TypeKind.Root)
            {
                return(GetRootMapping());
            }

            SoapAttributes a = GetAttributes(model.Type);

            string typeNs = _defaultNs;

            if (a.SoapType != null && a.SoapType.Namespace != null)
            {
                typeNs = a.SoapType.Namespace;
            }
            string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name);

            typeName = XmlConvert.EncodeLocalName(typeName);

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);

            if (mapping == null)
            {
                mapping           = new StructMapping();
                mapping.IsSoap    = true;
                mapping.TypeDesc  = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName  = typeName;
                if (a.SoapType != null)
                {
                    mapping.IncludeInSchema = a.SoapType.IncludeInSchema;
                }
                _typeScope.AddTypeMapping(mapping);
                _types.Add(typeName, typeNs, mapping);
                if (limiter.IsExceededLimit)
                {
                    limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    return(mapping);
                }

                limiter.Depth++;

                InitializeStructMembers(mapping, model, limiter);
                while (limiter.DeferredWorkItems.Count > 0)
                {
                    int index = limiter.DeferredWorkItems.Count - 1;
                    ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                    if (InitializeStructMembers(item.Mapping, item.Model, limiter))
                    {
                        //
                        // if InitializeStructMembers returns true, then there were *no* chages to the DeferredWorkItems
                        //
#if DEBUG
                        // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
                        if (index != limiter.DeferredWorkItems.Count - 1)
                        {
                            throw new InvalidOperationException(string.Format(ResXml.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed"));
                        }
                        if (item != limiter.DeferredWorkItems[index])
                        {
                            throw new InvalidOperationException(string.Format(ResXml.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed"));
                        }
#endif
                        // Remove the last work item
                        limiter.DeferredWorkItems.RemoveAt(index);
                    }
                }
                limiter.Depth--;
            }
            return(mapping);
        }
        private TypeMapping ImportTypeMapping(TypeModel model, string dataType, RecursionLimiter limiter)
        {
            if (dataType.Length > 0)
            {
                if (!model.TypeDesc.IsPrimitive)
                {
                    throw new InvalidOperationException(string.Format(ResXml.XmlInvalidDataTypeUsage, dataType, "SoapElementAttribute.DataType"));
                }
                TypeDesc td = _typeScope.GetTypeDesc(dataType, XmlSchema.Namespace);
                if (td == null)
                {
                    throw new InvalidOperationException(string.Format(ResXml.XmlInvalidXsdDataType, dataType, "SoapElementAttribute.DataType", new XmlQualifiedName(dataType, XmlSchema.Namespace).ToString()));
                }
                if (model.TypeDesc.FullName != td.FullName)
                {
                    throw new InvalidOperationException(string.Format(ResXml.XmlDataTypeMismatch, dataType, "SoapElementAttribute.DataType", model.TypeDesc.FullName));
                }
            }

            SoapAttributes a = GetAttributes(model.Type);

            if ((a.SoapFlags & ~SoapAttributeFlags.Type) != 0)
            {
                throw new InvalidOperationException(string.Format(ResXml.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(string.Format(ResXml.XmlUnsupportedSoapTypeKind, model.TypeDesc.FullName));
            }
        }