private void Preprocess()

in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/schema/Preprocessor.cs [542:815]


        private void Preprocess(XmlSchema schema, string targetNamespace, ArrayList imports)
        {
            XmlSchema prevRootSchemaForRedefine = null;
            if (schema.IsProcessing)
            {
                return;
            }
            schema.IsProcessing = true;

            string tns = schema.TargetNamespace;
            if (tns != null)
            {
                schema.TargetNamespace = tns = NameTable.Add(tns);
                if (tns.Length == 0)
                {
                    SendValidationEvent(ResXml.Sch_InvalidTargetNamespaceAttribute, schema);
                }
                else
                {
                    ParseUri(tns, ResXml.Sch_InvalidNamespace, schema);
                }
            }
            if (schema.Version != null)
            {
                XmlSchemaDatatype tokenDt = DatatypeImplementation.GetSimpleTypeFromTypeCode(XmlTypeCode.Token).Datatype;
                object version;
                Exception exception = tokenDt.TryParseValue(schema.Version, null, null, out version);
                if (exception != null)
                {
                    SendValidationEvent(ResXml.Sch_AttributeValueDataTypeDetailed, new string[] { "version", schema.Version, tokenDt.TypeCodeString, exception.Message }, exception, schema);
                }
                else
                {
                    schema.Version = (string)version;
                }
            }

            //Begin processing the schema after checking targetNamespace and verifying chameleon
            Cleanup(schema);

            for (int i = 0; i < schema.Includes.Count; ++i)
            {
                XmlSchemaExternal include = (XmlSchemaExternal)schema.Includes[i];
                XmlSchema externalSchema = include.Schema;
                SetParent(include, schema);
                PreprocessAnnotation(include);
                string loc = include.SchemaLocation;
                if (loc != null)
                {
                    ParseUri(loc, ResXml.Sch_InvalidSchemaLocation, include);
                }
                else if ((include.Compositor == Compositor.Include || include.Compositor == Compositor.Redefine) && externalSchema == null)
                {
                    SendValidationEvent(ResXml.Sch_MissRequiredAttribute, "schemaLocation", include);
                }

                switch (include.Compositor)
                {
                    case Compositor.Import:
                        XmlSchemaImport import = include as XmlSchemaImport;
                        string importNS = import.Namespace;
                        if (importNS == schema.TargetNamespace)
                        {
                            SendValidationEvent(ResXml.Sch_ImportTargetNamespace, include);
                        }
                        if (externalSchema != null)
                        {
                            if (importNS != externalSchema.TargetNamespace)
                            {
                                SendValidationEvent(ResXml.Sch_MismatchTargetNamespaceImport, importNS, externalSchema.TargetNamespace, import);
                            }
                            //SetParent(externalSchema, import);
                            prevRootSchemaForRedefine = _rootSchemaForRedefine;
                            _rootSchemaForRedefine = externalSchema; //Make the imported schema the root schema for redefines
                            Preprocess(externalSchema, importNS, imports);
                            _rootSchemaForRedefine = prevRootSchemaForRedefine; //Reset the root schema for redefines
                        }
                        else
                        {
                            if (importNS != null)
                            {
                                if (importNS.Length == 0)
                                {
                                    SendValidationEvent(ResXml.Sch_InvalidNamespaceAttribute, importNS, include);
                                }
                                else
                                {
                                    ParseUri(importNS, ResXml.Sch_InvalidNamespace, include);
                                }
                            }
                        }
                        break;
                    case Compositor.Include:
                        XmlSchema includedSchema = include.Schema;
                        if (includedSchema != null)
                        {
                            //SetParent(includedSchema, include);
                            goto default;
                        }
                        break;

                    case Compositor.Redefine:
                        if (externalSchema != null)
                        {
                            //SetParent(externalSchema, include); 
                            CleanupRedefine(include);
                            goto default;
                        }
                        break;

                    default: //For include, redefine common case
                        if (externalSchema.TargetNamespace != null)
                        {
                            if (schema.TargetNamespace != externalSchema.TargetNamespace)
                            { //namespaces for includes should be the same
                                SendValidationEvent(ResXml.Sch_MismatchTargetNamespaceInclude, externalSchema.TargetNamespace, schema.TargetNamespace, include);
                            }
                        }
                        else if (targetNamespace != null && targetNamespace.Length != 0)
                        { //Chameleon redefine
                            externalSchema = GetChameleonSchema(targetNamespace, externalSchema);
                            include.Schema = externalSchema; //Reset the schema property to the cloned schema
                        }
                        Preprocess(externalSchema, schema.TargetNamespace, imports);
                        break;
                }
            }

            //Begin processing the current schema passed to preprocess
            //Build the namespaces that can be referenced in the current schema
            _currentSchema = schema;
            BuildRefNamespaces(schema);
            ValidateIdAttribute(schema);

            _targetNamespace = targetNamespace == null ? string.Empty : targetNamespace;

            SetSchemaDefaults(schema);

            _processedExternals.Clear();
            XmlSchemaExternal external;
            for (int i = 0; i < schema.Includes.Count; i++)
            {
                external = (XmlSchemaExternal)schema.Includes[i];
                XmlSchema includedSchema = external.Schema;
                if (includedSchema != null)
                {
                    switch (external.Compositor)
                    {
                        case Compositor.Include:
                            if (_processedExternals[includedSchema] != null)
                            {
                                continue; //Already processed this included schema; TODO Need to look at other option than using HashTable
                            }
                            _processedExternals.Add(includedSchema, external);
                            CopyIncludedComponents(includedSchema, schema);
                            break;

                        case Compositor.Redefine:
                            if (_redefinedList == null)
                            {
                                _redefinedList = new ArrayList();
                            }
                            _redefinedList.Add(new RedefineEntry(external as XmlSchemaRedefine, _rootSchemaForRedefine));
                            if (_processedExternals[includedSchema] != null)
                            {
                                continue; //Already processed this included schema; TODO Need to look at other option than using HashTable
                            }
                            _processedExternals.Add(includedSchema, external);
                            CopyIncludedComponents(includedSchema, schema);
                            break;

                        case Compositor.Import:
                            if (includedSchema != _rootSchema)
                            {
                                XmlSchemaImport import = external as XmlSchemaImport;
                                string importNS = import.Namespace != null ? import.Namespace : string.Empty;
                                if (!imports.Contains(includedSchema))
                                { //TODO Change ImportedSchemas to Hashtable
                                    imports.Add(includedSchema);
                                }
                                if (!_rootSchema.ImportedNamespaces.Contains(importNS))
                                {
                                    _rootSchema.ImportedNamespaces.Add(importNS);
                                }
                            }
                            break;

                        default:
                            Debug.Assert(false);
                            break;
                    }
                }
                else if (external.Compositor == Compositor.Redefine)
                {
                    XmlSchemaRedefine redefine = external as XmlSchemaRedefine;
                    if (redefine.BaseUri == null)
                    {
                        for (int j = 0; j < redefine.Items.Count; ++j)
                        {
                            if (!(redefine.Items[j] is XmlSchemaAnnotation))
                            {
                                SendValidationEvent(ResXml.Sch_RedefineNoSchema, redefine);
                                break;
                            }
                        }
                    }
                }

                ValidateIdAttribute(external);
            }

            List<XmlSchemaObject> removeItemsList = new List<XmlSchemaObject>();
            XmlSchemaObjectCollection schemaItems = schema.Items;
            for (int i = 0; i < schemaItems.Count; ++i)
            {
                SetParent(schemaItems[i], schema);
                XmlSchemaAttribute attribute = schemaItems[i] as XmlSchemaAttribute;
                if (attribute != null)
                {
                    PreprocessAttribute(attribute);
                    AddToTable(schema.Attributes, attribute.QualifiedName, attribute);
                }
                else if (schemaItems[i] is XmlSchemaAttributeGroup)
                {
                    XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)schemaItems[i];
                    PreprocessAttributeGroup(attributeGroup);
                    AddToTable(schema.AttributeGroups, attributeGroup.QualifiedName, attributeGroup);
                }
                else if (schemaItems[i] is XmlSchemaComplexType)
                {
                    XmlSchemaComplexType complexType = (XmlSchemaComplexType)schemaItems[i];
                    PreprocessComplexType(complexType, false);
                    AddToTable(schema.SchemaTypes, complexType.QualifiedName, complexType);
                }
                else if (schemaItems[i] is XmlSchemaSimpleType)
                {
                    XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)schemaItems[i];
                    PreprocessSimpleType(simpleType, false);
                    AddToTable(schema.SchemaTypes, simpleType.QualifiedName, simpleType);
                }
                else if (schemaItems[i] is XmlSchemaElement)
                {
                    XmlSchemaElement element = (XmlSchemaElement)schemaItems[i];
                    PreprocessElement(element);
                    AddToTable(schema.Elements, element.QualifiedName, element);
                }
                else if (schemaItems[i] is XmlSchemaGroup)
                {
                    XmlSchemaGroup group = (XmlSchemaGroup)schemaItems[i];
                    PreprocessGroup(group);
                    AddToTable(schema.Groups, group.QualifiedName, group);
                }
                else if (schemaItems[i] is XmlSchemaNotation)
                {
                    XmlSchemaNotation notation = (XmlSchemaNotation)schemaItems[i];
                    PreprocessNotation(notation);
                    AddToTable(schema.Notations, notation.QualifiedName, notation);
                }
                else if (schemaItems[i] is XmlSchemaAnnotation)
                {
                    PreprocessAnnotation(schemaItems[i] as XmlSchemaAnnotation);
                }
                else
                {
                    SendValidationEvent(ResXml.Sch_InvalidCollection, (XmlSchemaObject)schemaItems[i]);
                    removeItemsList.Add(schemaItems[i]);
                }
            }

            for (int i = 0; i < removeItemsList.Count; ++i)
            {
                schema.Items.Remove(removeItemsList[i]);
            }
        }