The Labs \ Source Viewer \ SSCLI \ System.Xml.Schema \ Compiler

  1. //------------------------------------------------------------------------------
  2. // <copyright file="Compiler.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. // <owner current="true" primary="true">priyal</owner>
  15. //------------------------------------------------------------------------------
  16. namespace System.Xml.Schema
  17. {
  18.    
  19.     using System;
  20.     using System.Collections;
  21.     using System.Globalization;
  22.     using System.Text;
  23.     using System.Diagnostics;
  24.    
  25.     internal sealed class Compiler : BaseProcessor
  26.     {
  27.         string restrictionErrorMsg;
  28.         XmlSchemaObjectTable attributes = new XmlSchemaObjectTable();
  29.         XmlSchemaObjectTable attributeGroups = new XmlSchemaObjectTable();
  30.         XmlSchemaObjectTable elements = new XmlSchemaObjectTable();
  31.         XmlSchemaObjectTable schemaTypes = new XmlSchemaObjectTable();
  32.         XmlSchemaObjectTable groups = new XmlSchemaObjectTable();
  33.         XmlSchemaObjectTable notations = new XmlSchemaObjectTable();
  34.         XmlSchemaObjectTable examplars = new XmlSchemaObjectTable();
  35.         XmlSchemaObjectTable identityConstraints = new XmlSchemaObjectTable();
  36.         Stack complexTypeStack = new Stack();
  37.         Hashtable schemasToCompile = new Hashtable();
  38.         Hashtable importedSchemas = new Hashtable();
  39.        
  40.         XmlSchema schemaForSchema;
  41.        
  42.         public Compiler(XmlNameTable nameTable, ValidationEventHandler eventHandler, XmlSchema schemaForSchema, XmlSchemaCompilationSettings compilationSettings) : base(nameTable, null, eventHandler, compilationSettings)
  43.         {
  44.             this.schemaForSchema = schemaForSchema;
  45.         }
  46.        
  47.         public bool Execute(XmlSchemaSet schemaSet, SchemaInfo schemaCompiledInfo)
  48.         {
  49.             Compile();
  50.             if (!HasErrors) {
  51.                 Output(schemaCompiledInfo);
  52.                 schemaSet.elements = elements;
  53.                 schemaSet.attributes = attributes;
  54.                 schemaSet.schemaTypes = schemaTypes;
  55.                 schemaSet.substitutionGroups = examplars;
  56.             }
  57.             return !HasErrors;
  58.         }
  59.        
  60.         internal void Prepare(XmlSchema schema, bool cleanup)
  61.         {
  62.             if (schemasToCompile[schema] != null) {
  63.                 return;
  64.             }
  65.             schemasToCompile.Add(schema, schema);
  66.             foreach (XmlSchemaElement element in schema.Elements.Values) {
  67.                 if (cleanup) {
  68.                     CleanupElement(element);
  69.                 }
  70.                 AddToTable(elements, element.QualifiedName, element);
  71.             }
  72.             foreach (XmlSchemaAttribute attribute in schema.Attributes.Values) {
  73.                 if (cleanup) {
  74.                     CleanupAttribute(attribute);
  75.                 }
  76.                 AddToTable(attributes, attribute.QualifiedName, attribute);
  77.             }
  78.             foreach (XmlSchemaGroup group in schema.Groups.Values) {
  79.                 if (cleanup) {
  80.                     CleanupGroup(group);
  81.                 }
  82.                 AddToTable(groups, group.QualifiedName, group);
  83.             }
  84.             foreach (XmlSchemaAttributeGroup attributeGroup in schema.AttributeGroups.Values) {
  85.                 if (cleanup) {
  86.                     CleanupAttributeGroup(attributeGroup);
  87.                 }
  88.                 AddToTable(attributeGroups, attributeGroup.QualifiedName, attributeGroup);
  89.             }
  90.             foreach (XmlSchemaType type in schema.SchemaTypes.Values) {
  91.                 if (cleanup) {
  92.                     XmlSchemaComplexType ct = type as XmlSchemaComplexType;
  93.                     if (ct != null) {
  94.                         CleanupComplexType(ct);
  95.                     }
  96.                     else {
  97.                         CleanupSimpleType(type as XmlSchemaSimpleType);
  98.                     }
  99.                 }
  100.                 AddToTable(schemaTypes, type.QualifiedName, type);
  101.             }
  102.             foreach (XmlSchemaNotation notation in schema.Notations.Values) {
  103.                 AddToTable(notations, notation.QualifiedName, notation);
  104.             }
  105.             foreach (XmlSchemaIdentityConstraint ic in schema.IdentityConstraints.Values) {
  106.                 AddToTable(identityConstraints, ic.QualifiedName, ic);
  107.             }
  108.         }
  109.        
  110.         private void UpdateSForSSimpleTypes()
  111.         {
  112.             Debug.Assert(schemaForSchema != null);
  113.             XmlSchemaSimpleType[] schemaSimpleTypes = DatatypeImplementation.GetBuiltInTypes();
  114.             XmlSchemaSimpleType builtInType;
  115.             //Using enumToTypeCode array; indexed by XmlTypeCode; Start indexing from 12 since schema types start there and iterate till Length - 2 as the last 2 are xquery types
  116.             int numberOfSchemaTypes = schemaSimpleTypes.Length - 3;
  117.             //skip last 2 xquery types
  118.             for (int i = 12; i < numberOfSchemaTypes; i++) {
  119.                 builtInType = schemaSimpleTypes[i];
  120.                 schemaForSchema.SchemaTypes.Replace(builtInType.QualifiedName, builtInType);
  121.                 this.schemaTypes.Replace(builtInType.QualifiedName, builtInType);
  122.             }
  123.         }
  124.        
  125.         private void Output(SchemaInfo schemaInfo)
  126.         {
  127.             string tns;
  128.             foreach (XmlSchema schema in schemasToCompile.Values) {
  129.                 tns = schema.TargetNamespace;
  130.                 if (tns == null) {
  131.                     tns = string.Empty;
  132.                 }
  133.                 schemaInfo.TargetNamespaces[tns] = tns;
  134.             }
  135.             foreach (XmlSchemaElement element in elements.Values) {
  136.                 schemaInfo.ElementDecls.Add(element.QualifiedName, element.ElementDecl);
  137.             }
  138.             foreach (XmlSchemaAttribute attribute in attributes.Values) {
  139.                 schemaInfo.AttributeDecls.Add(attribute.QualifiedName, attribute.AttDef);
  140.             }
  141.             foreach (XmlSchemaType type in schemaTypes.Values) {
  142.                 schemaInfo.ElementDeclsByType.Add(type.QualifiedName, type.ElementDecl);
  143.             }
  144.             foreach (XmlSchemaNotation notation in notations.Values) {
  145.                 SchemaNotation no = new SchemaNotation(notation.QualifiedName);
  146.                 no.SystemLiteral = notation.System;
  147.                 no.Pubid = notation.Public;
  148.                 if (schemaInfo.Notations[no.Name.Name] == null) {
  149.                     schemaInfo.Notations.Add(no.Name.Name, no);
  150.                 }
  151.             }
  152.            
  153.         }
  154.        
  155.         internal void ImportAllCompiledSchemas(XmlSchemaSet schemaSet)
  156.         {
  157.             XmlSchema currentSchema;
  158.             int schemaIndex;
  159.             SortedList schemas = schemaSet.SortedSchemas;
  160.             for (schemaIndex = 0; schemaIndex < schemas.Count; schemaIndex++) {
  161.                 currentSchema = (XmlSchema)schemas.GetByIndex(schemaIndex);
  162.                 if (currentSchema.IsCompiledBySet) {
  163.                     //Import already compiled schemas
  164.                     Prepare(currentSchema, false);
  165.                 }
  166.             }
  167.         }
  168.        
  169.         internal bool Compile()
  170.         {
  171.             schemaTypes.Insert(DatatypeImplementation.QnAnyType, XmlSchemaComplexType.AnyType);
  172.             if (schemaForSchema != null) {
  173.                 //Get our built-in types
  174.                 schemaForSchema.SchemaTypes.Replace(DatatypeImplementation.QnAnyType, XmlSchemaComplexType.AnyType);
  175.                 UpdateSForSSimpleTypes();
  176.             }
  177.             foreach (XmlSchemaGroup group in groups.Values) {
  178.                 CompileGroup(group);
  179.             }
  180.             foreach (XmlSchemaAttributeGroup attributeGroup in attributeGroups.Values) {
  181.                 CompileAttributeGroup(attributeGroup);
  182.             }
  183.             foreach (XmlSchemaType type in schemaTypes.Values) {
  184.                 XmlSchemaComplexType ct = type as XmlSchemaComplexType;
  185.                 if (ct != null) {
  186.                     CompileComplexType(ct);
  187.                 }
  188.                 else {
  189.                     CompileSimpleType((XmlSchemaSimpleType)type);
  190.                 }
  191.             }
  192.             foreach (XmlSchemaElement element in elements.Values) {
  193.                 if (element.ElementDecl == null) {
  194.                     CompileElement(element);
  195.                 }
  196.             }
  197.             foreach (XmlSchemaAttribute attribute in attributes.Values) {
  198.                 if (attribute.AttDef == null) {
  199.                     CompileAttribute(attribute);
  200.                 }
  201.             }
  202.             foreach (XmlSchemaIdentityConstraint identityConstraint in identityConstraints.Values) {
  203.                 if (identityConstraint.CompiledConstraint == null) {
  204.                     CompileIdentityConstraint(identityConstraint);
  205.                 }
  206.             }
  207.             while (this.complexTypeStack.Count > 0) {
  208.                 XmlSchemaComplexType type = (XmlSchemaComplexType)complexTypeStack.Pop();
  209.                 CompileComplexTypeElements(type);
  210.             }
  211.            
  212.             ProcessSubstitutionGroups();
  213.            
  214.             foreach (XmlSchemaType type in schemaTypes.Values) {
  215.                 XmlSchemaComplexType localType = type as XmlSchemaComplexType;
  216.                 if (localType != null) {
  217.                     CheckParticleDerivation(localType);
  218.                 }
  219.             }
  220.            
  221.             foreach (XmlSchemaElement element in elements.Values) {
  222.                 XmlSchemaComplexType localComplexType = element.ElementSchemaType as XmlSchemaComplexType;
  223.                 if (localComplexType != null && element.SchemaTypeName == XmlQualifiedName.Empty) {
  224.                     // only local schemaTypes
  225.                     CheckParticleDerivation(localComplexType);
  226.                 }
  227.             }
  228.             foreach (XmlSchemaGroup group in groups.Values) {
  229.                 //Check particle derivation for redefined groups
  230.                 XmlSchemaGroup baseGroup = group.Redefined;
  231.                 if (baseGroup != null) {
  232.                     RecursivelyCheckRedefinedGroups(group, baseGroup);
  233.                 }
  234.             }
  235.            
  236.             foreach (XmlSchemaAttributeGroup attributeGroup in attributeGroups.Values) {
  237.                 XmlSchemaAttributeGroup baseAttributeGroup = attributeGroup.Redefined;
  238.                 if (baseAttributeGroup != null) {
  239.                     RecursivelyCheckRedefinedAttributeGroups(attributeGroup, baseAttributeGroup);
  240.                 }
  241.             }
  242.             return !HasErrors;
  243.         }
  244.        
  245.         private void CleanupAttribute(XmlSchemaAttribute attribute)
  246.         {
  247.             if (attribute.SchemaType != null) {
  248.                 CleanupSimpleType((XmlSchemaSimpleType)attribute.SchemaType);
  249.             }
  250.             attribute.AttDef = null;
  251.         }
  252.        
  253.         private void CleanupAttributeGroup(XmlSchemaAttributeGroup attributeGroup)
  254.         {
  255.             CleanupAttributes(attributeGroup.Attributes);
  256.             attributeGroup.AttributeUses.Clear();
  257.             attributeGroup.AttributeWildcard = null;
  258.             if (attributeGroup.Redefined != null) {
  259.                 CleanupAttributeGroup(attributeGroup.Redefined);
  260.             }
  261.         }
  262.        
  263.         private void CleanupComplexType(XmlSchemaComplexType complexType)
  264.         {
  265.             if (complexType.QualifiedName == DatatypeImplementation.QnAnyType) {
  266.                 //if it is built-in anyType dont clean it.
  267.                 return;
  268.             }
  269.             if (complexType.ContentModel != null) {
  270.                 //simpleContent or complexContent
  271.                 if (complexType.ContentModel is XmlSchemaSimpleContent) {
  272.                     XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel;
  273.                     if (simpleContent.Content is XmlSchemaSimpleContentExtension) {
  274.                         XmlSchemaSimpleContentExtension simpleExtension = (XmlSchemaSimpleContentExtension)simpleContent.Content;
  275.                         CleanupAttributes(simpleExtension.Attributes);
  276.                     }
  277.                     else {
  278.                         //simpleContent.Content is XmlSchemaSimpleContentRestriction
  279.                         XmlSchemaSimpleContentRestriction simpleRestriction = (XmlSchemaSimpleContentRestriction)simpleContent.Content;
  280.                         CleanupAttributes(simpleRestriction.Attributes);
  281.                     }
  282.                 }
  283.                 else {
  284.                     // complexType.ContentModel is XmlSchemaComplexContent
  285.                     XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)complexType.ContentModel;
  286.                     if (complexContent.Content is XmlSchemaComplexContentExtension) {
  287.                         XmlSchemaComplexContentExtension complexExtension = (XmlSchemaComplexContentExtension)complexContent.Content;
  288.                         CleanupParticle(complexExtension.Particle);
  289.                         CleanupAttributes(complexExtension.Attributes);
  290.                        
  291.                     }
  292.                     else {
  293.                         //XmlSchemaComplexContentRestriction
  294.                         XmlSchemaComplexContentRestriction complexRestriction = (XmlSchemaComplexContentRestriction)complexContent.Content;
  295.                         CleanupParticle(complexRestriction.Particle);
  296.                         CleanupAttributes(complexRestriction.Attributes);
  297.                     }
  298.                 }
  299.             }
  300.             else {
  301.                 //equals XmlSchemaComplexContent with baseType is anyType
  302.                 CleanupParticle(complexType.Particle);
  303.                 CleanupAttributes(complexType.Attributes);
  304.             }
  305.             complexType.LocalElements.Clear();
  306.             complexType.AttributeUses.Clear();
  307.             complexType.SetAttributeWildcard(null);
  308.             complexType.SetContentTypeParticle(XmlSchemaParticle.Empty);
  309.             complexType.ElementDecl = null;
  310.             complexType.HasDuplicateDecls = false;
  311.             complexType.HasWildCard = false;
  312.            
  313.             //Clean up the original type if this is a redefined type
  314.             if (complexType.Redefined != null) {
  315.                 CleanupComplexType(complexType.Redefined as XmlSchemaComplexType);
  316.             }
  317.         }
  318.        
  319.         private void CleanupSimpleType(XmlSchemaSimpleType simpleType)
  320.         {
  321.             if (simpleType == XmlSchemaType.GetBuiltInSimpleType(simpleType.TypeCode)) {
  322.                 //If it is a built-in simple type dont clean up
  323.                 return;
  324.             }
  325.             simpleType.ElementDecl = null;
  326.             //Clean up the original group if this is a redefined group
  327.             if (simpleType.Redefined != null) {
  328.                 CleanupSimpleType(simpleType.Redefined as XmlSchemaSimpleType);
  329.             }
  330.         }
  331.        
  332.         private void CleanupElement(XmlSchemaElement element)
  333.         {
  334.             if (element.SchemaType != null) {
  335.                 XmlSchemaComplexType complexType = element.SchemaType as XmlSchemaComplexType;
  336.                 if (complexType != null) {
  337.                     CleanupComplexType(complexType);
  338.                 }
  339.                 else {
  340.                     CleanupSimpleType((XmlSchemaSimpleType)element.SchemaType);
  341.                 }
  342.             }
  343.             foreach (XmlSchemaIdentityConstraint constr in element.Constraints) {
  344.                 constr.CompiledConstraint = null;
  345.             }
  346.             element.ElementDecl = null;
  347.             element.IsLocalTypeDerivationChecked = false;
  348.             //clear Local element type derivation check
  349.         }
  350.        
  351.         private void CleanupAttributes(XmlSchemaObjectCollection attributes)
  352.         {
  353.             foreach (XmlSchemaObject obj in attributes) {
  354.                 if (obj is XmlSchemaAttribute) {
  355.                     CleanupAttribute((XmlSchemaAttribute)obj);
  356.                 }
  357.             }
  358.         }
  359.        
  360.         private void CleanupGroup(XmlSchemaGroup group)
  361.         {
  362.             CleanupParticle(group.Particle);
  363.             group.CanonicalParticle = null;
  364.             //Clean up the original group if this is a redefined group
  365.             if (group.Redefined != null) {
  366.                 CleanupGroup(group.Redefined);
  367.             }
  368.         }
  369.        
  370.         private void CleanupParticle(XmlSchemaParticle particle)
  371.         {
  372.             if (particle is XmlSchemaElement) {
  373.                 CleanupElement((XmlSchemaElement)particle);
  374.             }
  375.             else if (particle is XmlSchemaGroupBase) {
  376.                 foreach (XmlSchemaParticle p in ((XmlSchemaGroupBase)particle).Items) {
  377.                     CleanupParticle(p);
  378.                 }
  379.             }
  380.         }
  381.        
  382.         private void ProcessSubstitutionGroups()
  383.         {
  384.             foreach (XmlSchemaElement element in this.elements.Values) {
  385.                 if (!element.SubstitutionGroup.IsEmpty) {
  386.                     XmlSchemaElement headElement = this.elements[element.SubstitutionGroup] as XmlSchemaElement;
  387.                     if (headElement == null) {
  388.                         SendValidationEvent(Res.Sch_NoExamplar, element);
  389.                         continue;
  390.                     }
  391.                     //Check derivation of member's type against head's type
  392.                     if (!XmlSchemaType.IsDerivedFrom(element.ElementSchemaType, headElement.ElementSchemaType, headElement.FinalResolved)) {
  393.                         SendValidationEvent(Res.Sch_InvalidSubstitutionMember, (element.QualifiedName).ToString(), (headElement.QualifiedName).ToString(), element);
  394.                     }
  395.                     if ((headElement.BlockResolved & XmlSchemaDerivationMethod.Substitution) != 0) {
  396.                         //head element blocks substitution, dont build substGroup
  397.                         continue;
  398.                     }
  399.                     //Create substitutionGroup
  400.                     XmlSchemaSubstitutionGroup substitutionGroup = (XmlSchemaSubstitutionGroup)this.examplars[element.SubstitutionGroup];
  401.                     if (substitutionGroup == null) {
  402.                         substitutionGroup = new XmlSchemaSubstitutionGroup();
  403.                         substitutionGroup.Examplar = element.SubstitutionGroup;
  404.                         examplars.Add(element.SubstitutionGroup, substitutionGroup);
  405.                     }
  406.                     ArrayList members = substitutionGroup.Members;
  407.                     if (!members.Contains(element)) {
  408.                         //Members might contain element if the same schema is included and imported through different paths. Imp, hence will be added to set directly
  409.                         members.Add(element);
  410.                     }
  411.                 }
  412.             }
  413.            
  414.             //Check the subst groups that we just built
  415.             foreach (XmlSchemaSubstitutionGroup substitutionGroup in examplars.Values) {
  416.                 CompileSubstitutionGroup(substitutionGroup);
  417.             }
  418.         }
  419.         private void CompileSubstitutionGroup(XmlSchemaSubstitutionGroup substitutionGroup)
  420.         {
  421.             if (substitutionGroup.IsProcessing) {
  422.                 foreach (XmlSchemaElement element in substitutionGroup.Members) {
  423.                     SendValidationEvent(Res.Sch_SubstitutionCircularRef, element);
  424.                     return;
  425.                 }
  426.             }
  427.             XmlSchemaElement examplar = (XmlSchemaElement)elements[substitutionGroup.Examplar];
  428.             Debug.Assert(examplar != null);
  429.             //Headelement presence is checked while building subst groups
  430.             if (substitutionGroup.Members.Contains(examplar)) {
  431.                 // already checked
  432.                 return;
  433.             }
  434.             substitutionGroup.IsProcessing = true;
  435.             try {
  436.                 if (examplar.FinalResolved == XmlSchemaDerivationMethod.All) {
  437.                     SendValidationEvent(Res.Sch_InvalidExamplar, examplar);
  438.                 }
  439.                 //Build transitive members
  440.                 ArrayList newMembers = null;
  441.                 foreach (XmlSchemaElement element in substitutionGroup.Members) {
  442.                     //Chain to other head's that are members of this head's substGroup
  443.                     XmlSchemaSubstitutionGroup g = (XmlSchemaSubstitutionGroup)examplars[element.QualifiedName];
  444.                     if (g != null) {
  445.                         CompileSubstitutionGroup(g);
  446.                         foreach (XmlSchemaElement element1 in g.Members) {
  447.                             if (element1 != element) {
  448.                                 //Exclude the head
  449.                                 if (newMembers == null) {
  450.                                     newMembers = new ArrayList();
  451.                                 }
  452.                                 newMembers.Add(element1);
  453.                             }
  454.                         }
  455.                     }
  456.                 }
  457.                 if (newMembers != null) {
  458.                     foreach (XmlSchemaElement newMember in newMembers) {
  459.                         substitutionGroup.Members.Add(newMember);
  460.                     }
  461.                 }
  462.                 substitutionGroup.Members.Add(examplar);
  463.                 // Compiled mark
  464.             }
  465.             finally {
  466.                 substitutionGroup.IsProcessing = false;
  467.             }
  468.         }
  469.        
  470.         private void RecursivelyCheckRedefinedGroups(XmlSchemaGroup redefinedGroup, XmlSchemaGroup baseGroup)
  471.         {
  472.             if (baseGroup.Redefined != null) {
  473.                 RecursivelyCheckRedefinedGroups(baseGroup, baseGroup.Redefined);
  474.             }
  475.             if (redefinedGroup.SelfReferenceCount == 0) {
  476.                 if (baseGroup.CanonicalParticle == null) {
  477.                     baseGroup.CanonicalParticle = CannonicalizeParticle(baseGroup.Particle, true);
  478.                 }
  479.                 if (redefinedGroup.CanonicalParticle == null) {
  480.                     redefinedGroup.CanonicalParticle = CannonicalizeParticle(redefinedGroup.Particle, true);
  481.                 }
  482.                 CompileParticleElements(redefinedGroup.CanonicalParticle);
  483.                 CompileParticleElements(baseGroup.CanonicalParticle);
  484.                 CheckParticleDerivation(redefinedGroup.CanonicalParticle, baseGroup.CanonicalParticle);
  485.             }
  486.         }
  487.        
  488.         private void RecursivelyCheckRedefinedAttributeGroups(XmlSchemaAttributeGroup attributeGroup, XmlSchemaAttributeGroup baseAttributeGroup)
  489.         {
  490.             if (baseAttributeGroup.Redefined != null) {
  491.                 RecursivelyCheckRedefinedAttributeGroups(baseAttributeGroup, baseAttributeGroup.Redefined);
  492.             }
  493.             if (attributeGroup.SelfReferenceCount == 0) {
  494.                 CompileAttributeGroup(baseAttributeGroup);
  495.                 CompileAttributeGroup(attributeGroup);
  496.                 CheckAtrributeGroupRestriction(baseAttributeGroup, attributeGroup);
  497.             }
  498.         }
  499.        
  500.         private void CompileGroup(XmlSchemaGroup group)
  501.         {
  502.             if (group.IsProcessing) {
  503.                 SendValidationEvent(Res.Sch_GroupCircularRef, group);
  504.                 group.CanonicalParticle = XmlSchemaParticle.Empty;
  505.             }
  506.             else {
  507.                 group.IsProcessing = true;
  508.                 if (group.CanonicalParticle == null) {
  509.                     group.CanonicalParticle = CannonicalizeParticle(group.Particle, true);
  510.                 }
  511.                 Debug.Assert(group.CanonicalParticle != null);
  512.                 group.IsProcessing = false;
  513.                 //Not enclosung in try -finally as cannonicalizeParticle will not throw exception
  514.             }
  515.         }
  516.        
  517.         private void CompileSimpleType(XmlSchemaSimpleType simpleType)
  518.         {
  519.             if (simpleType.IsProcessing) {
  520.                 throw new XmlSchemaException(Res.Sch_TypeCircularRef, simpleType);
  521.             }
  522.             if (simpleType.ElementDecl != null) {
  523.                 // already compiled
  524.                 return;
  525.             }
  526.             simpleType.IsProcessing = true;
  527.             try {
  528.                 if (simpleType.Content is XmlSchemaSimpleTypeList) {
  529.                     XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)simpleType.Content;
  530.                     XmlSchemaDatatype datatype;
  531.                     simpleType.SetBaseSchemaType(DatatypeImplementation.AnySimpleType);
  532.                     if (list.ItemTypeName.IsEmpty) {
  533.                         CompileSimpleType(list.ItemType);
  534.                         list.BaseItemType = list.ItemType;
  535.                         datatype = list.ItemType.Datatype;
  536.                     }
  537.                     else {
  538.                         XmlSchemaSimpleType type = GetSimpleType(list.ItemTypeName);
  539.                         if (type != null) {
  540.                             if ((type.FinalResolved & XmlSchemaDerivationMethod.List) != 0) {
  541.                                 SendValidationEvent(Res.Sch_BaseFinalList, simpleType);
  542.                             }
  543.                             list.BaseItemType = type;
  544.                             datatype = type.Datatype;
  545.                         }
  546.                         else {
  547.                             throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, list.ItemTypeName.ToString(), list);
  548.                         }
  549.                     }
  550.                     simpleType.SetDatatype(datatype.DeriveByList(simpleType));
  551.                     simpleType.SetDerivedBy(XmlSchemaDerivationMethod.List);
  552.                 }
  553.                 else if (simpleType.Content is XmlSchemaSimpleTypeRestriction) {
  554.                     XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)simpleType.Content;
  555.                     XmlSchemaDatatype datatype;
  556.                     if (restriction.BaseTypeName.IsEmpty) {
  557.                         CompileSimpleType(restriction.BaseType);
  558.                         simpleType.SetBaseSchemaType(restriction.BaseType);
  559.                         datatype = restriction.BaseType.Datatype;
  560.                     }
  561.                     else if (simpleType.Redefined != null && restriction.BaseTypeName == simpleType.Redefined.QualifiedName) {
  562.                         CompileSimpleType((XmlSchemaSimpleType)simpleType.Redefined);
  563.                         simpleType.SetBaseSchemaType(simpleType.Redefined.BaseXmlSchemaType);
  564.                         datatype = simpleType.Redefined.Datatype;
  565.                     }
  566.                     else {
  567.                         if (restriction.BaseTypeName.Equals(DatatypeImplementation.QnAnySimpleType)) {
  568.                             XmlSchema parentSchema = Preprocessor.GetParentSchema(simpleType);
  569.                             if (parentSchema.TargetNamespace != XmlSchema.Namespace) {
  570.                                 //If it is not SForS, then error
  571.                                 throw new XmlSchemaException(Res.Sch_InvalidSimpleTypeRestriction, restriction.BaseTypeName.ToString(), simpleType);
  572.                             }
  573.                         }
  574.                         XmlSchemaSimpleType type = GetSimpleType(restriction.BaseTypeName);
  575.                         if (type != null) {
  576.                             if ((type.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
  577.                                 SendValidationEvent(Res.Sch_BaseFinalRestriction, simpleType);
  578.                             }
  579.                             simpleType.SetBaseSchemaType(type);
  580.                             datatype = type.Datatype;
  581.                         }
  582.                         else {
  583.                             throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, restriction.BaseTypeName.ToString(), restriction);
  584.                         }
  585.                     }
  586.                     simpleType.SetDatatype(datatype.DeriveByRestriction(restriction.Facets, NameTable, simpleType));
  587.                     simpleType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  588.                 }
  589.                 else {
  590.                     //simpleType.Content is XmlSchemaSimpleTypeUnion
  591.                     XmlSchemaSimpleType[] baseTypes = CompileBaseMemberTypes(simpleType);
  592.                     simpleType.SetBaseSchemaType(DatatypeImplementation.AnySimpleType);
  593.                     simpleType.SetDatatype(XmlSchemaDatatype.DeriveByUnion(baseTypes, simpleType));
  594.                     simpleType.SetDerivedBy(XmlSchemaDerivationMethod.Union);
  595.                 }
  596.             }
  597.             catch (XmlSchemaException e) {
  598.                 if (e.SourceSchemaObject == null) {
  599.                     e.SetSource(simpleType);
  600.                 }
  601.                 SendValidationEvent(e);
  602.                 simpleType.SetDatatype(DatatypeImplementation.AnySimpleType.Datatype);
  603.             }
  604.             finally {
  605.                 SchemaElementDecl decl = new SchemaElementDecl();
  606.                 decl.ContentValidator = ContentValidator.TextOnly;
  607.                 decl.SchemaType = simpleType;
  608.                 decl.Datatype = simpleType.Datatype;
  609.                 simpleType.ElementDecl = decl;
  610.                 simpleType.IsProcessing = false;
  611.             }
  612.         }
  613.        
  614.         private XmlSchemaSimpleType[] CompileBaseMemberTypes(XmlSchemaSimpleType simpleType)
  615.         {
  616.             XmlSchemaSimpleType unionMember;
  617.             ArrayList memberTypeDefinitions = new ArrayList();
  618.            
  619.             XmlSchemaSimpleTypeUnion mainUnion = (XmlSchemaSimpleTypeUnion)simpleType.Content;
  620.            
  621.             Array mainMemberTypes = mainUnion.MemberTypes;
  622.             if (mainMemberTypes != null) {
  623.                 foreach (XmlQualifiedName memberName in mainMemberTypes) {
  624.                     unionMember = GetSimpleType(memberName);
  625.                     if (unionMember != null) {
  626.                         if (unionMember.Datatype.Variety == XmlSchemaDatatypeVariety.Union) {
  627.                             //union of union
  628.                             CheckUnionType(unionMember, memberTypeDefinitions, simpleType);
  629.                         }
  630.                         else {
  631.                             //its list or atomic
  632.                             memberTypeDefinitions.Add(unionMember);
  633.                         }
  634.                         //Check derivation method of the member that is referenced
  635.                         if ((unionMember.FinalResolved & XmlSchemaDerivationMethod.Union) != 0) {
  636.                             SendValidationEvent(Res.Sch_BaseFinalUnion, simpleType);
  637.                         }
  638.                     }
  639.                     else {
  640.                         throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, memberName.ToString(), mainUnion);
  641.                     }
  642.                 }
  643.             }
  644.            
  645.             //Now add the baseTypes that are defined inside the union itself
  646.             XmlSchemaObjectCollection mainBaseTypes = mainUnion.BaseTypes;
  647.             //TODO check for null
  648.             if (mainBaseTypes != null) {
  649.                 foreach (XmlSchemaSimpleType st in mainBaseTypes) {
  650.                     CompileSimpleType(st);
  651.                     if (st.Datatype.Variety == XmlSchemaDatatypeVariety.Union) {
  652.                         //union of union
  653.                         CheckUnionType(st, memberTypeDefinitions, simpleType);
  654.                     }
  655.                     else {
  656.                         //its list or atomic
  657.                         memberTypeDefinitions.Add(st);
  658.                     }
  659.                 }
  660.             }
  661.             //set all types
  662.             mainUnion.SetBaseMemberTypes(memberTypeDefinitions.ToArray(typeof(XmlSchemaSimpleType)) as XmlSchemaSimpleType[]);
  663.             return mainUnion.BaseMemberTypes;
  664.         }
  665.        
  666.         private void CheckUnionType(XmlSchemaSimpleType unionMember, ArrayList memberTypeDefinitions, XmlSchemaSimpleType parentType)
  667.         {
  668.             XmlSchemaDatatype unionDatatype = unionMember.Datatype;
  669.             if (unionMember.DerivedBy == XmlSchemaDerivationMethod.Restriction && (unionDatatype.HasLexicalFacets || unionDatatype.HasValueFacets)) {
  670.                 SendValidationEvent(Res.Sch_UnionFromUnion, parentType);
  671.             }
  672.             else {
  673.                 Datatype_union uniondt = unionMember.Datatype as Datatype_union;
  674.                 memberTypeDefinitions.AddRange(uniondt.BaseMemberTypes);
  675.             }
  676.         }
  677.        
  678.         private void CompileComplexType(XmlSchemaComplexType complexType)
  679.         {
  680.             if (complexType.ElementDecl != null) {
  681.                 //already compiled
  682.                 return;
  683.             }
  684.             if (complexType.IsProcessing) {
  685.                 SendValidationEvent(Res.Sch_TypeCircularRef, complexType);
  686.                 return;
  687.             }
  688.             complexType.IsProcessing = true;
  689.             try {
  690.                 if (complexType.ContentModel != null) {
  691.                     //simpleContent or complexContent
  692.                     if (complexType.ContentModel is XmlSchemaSimpleContent) {
  693.                         XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel;
  694.                         complexType.SetContentType(XmlSchemaContentType.TextOnly);
  695.                         if (simpleContent.Content is XmlSchemaSimpleContentExtension) {
  696.                             CompileSimpleContentExtension(complexType, (XmlSchemaSimpleContentExtension)simpleContent.Content);
  697.                         }
  698.                         else {
  699.                             //simpleContent.Content is XmlSchemaSimpleContentRestriction
  700.                             CompileSimpleContentRestriction(complexType, (XmlSchemaSimpleContentRestriction)simpleContent.Content);
  701.                         }
  702.                     }
  703.                     else {
  704.                         // complexType.ContentModel is XmlSchemaComplexContent
  705.                         XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)complexType.ContentModel;
  706.                         if (complexContent.Content is XmlSchemaComplexContentExtension) {
  707.                             CompileComplexContentExtension(complexType, complexContent, (XmlSchemaComplexContentExtension)complexContent.Content);
  708.                         }
  709.                         else {
  710.                             // complexContent.Content is XmlSchemaComplexContentRestriction
  711.                             CompileComplexContentRestriction(complexType, complexContent, (XmlSchemaComplexContentRestriction)complexContent.Content);
  712.                         }
  713.                     }
  714.                 }
  715.                 else {
  716.                     //equals XmlSchemaComplexContent with baseType is anyType
  717.                     complexType.SetBaseSchemaType(XmlSchemaComplexType.AnyType);
  718.                     CompileLocalAttributes(XmlSchemaComplexType.AnyType, complexType, complexType.Attributes, complexType.AnyAttribute, XmlSchemaDerivationMethod.Restriction);
  719.                     complexType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  720.                     complexType.SetContentTypeParticle(CompileContentTypeParticle(complexType.Particle));
  721.                     complexType.SetContentType(GetSchemaContentType(complexType, null, complexType.ContentTypeParticle));
  722.                 }
  723.                 if (complexType.ContainsIdAttribute(true)) {
  724.                     SendValidationEvent(Res.Sch_TwoIdAttrUses, complexType);
  725.                 }
  726.                 SchemaElementDecl decl = new SchemaElementDecl();
  727.                 decl.ContentValidator = CompileComplexContent(complexType);
  728.                 decl.SchemaType = complexType;
  729.                 decl.IsAbstract = complexType.IsAbstract;
  730.                 decl.Datatype = complexType.Datatype;
  731.                 decl.Block = complexType.BlockResolved;
  732.                 decl.AnyAttribute = complexType.AttributeWildcard;
  733.                 foreach (XmlSchemaAttribute attribute in complexType.AttributeUses.Values) {
  734.                     if (attribute.Use == XmlSchemaUse.Prohibited) {
  735.                         if (decl.ProhibitedAttributes[attribute.QualifiedName] == null) {
  736.                             decl.ProhibitedAttributes.Add(attribute.QualifiedName, attribute.QualifiedName);
  737.                         }
  738.                     }
  739.                     else {
  740.                         if (decl.AttDefs[attribute.QualifiedName] == null && attribute.AttDef != null && attribute.AttDef.Name != XmlQualifiedName.Empty && attribute.AttDef != SchemaAttDef.Empty) {
  741.                             decl.AddAttDef(attribute.AttDef);
  742.                         }
  743.                     }
  744.                 }
  745.                 decl.EndAddAttDef();
  746.                 complexType.ElementDecl = decl;
  747.             }
  748.             finally {
  749.                 complexType.IsProcessing = false;
  750.             }
  751.         }
  752.        
  753.        
  754.         private void CompileSimpleContentExtension(XmlSchemaComplexType complexType, XmlSchemaSimpleContentExtension simpleExtension)
  755.         {
  756.             XmlSchemaComplexType baseType = null;
  757.             if (complexType.Redefined != null && simpleExtension.BaseTypeName == complexType.Redefined.QualifiedName) {
  758.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  759.                 CompileComplexType(baseType);
  760.                 complexType.SetBaseSchemaType(baseType);
  761.                 complexType.SetDatatype(baseType.Datatype);
  762.             }
  763.             else {
  764.                 XmlSchemaType bto = GetAnySchemaType(simpleExtension.BaseTypeName);
  765.                 if (bto == null) {
  766.                     SendValidationEvent(Res.Sch_UndeclaredType, simpleExtension.BaseTypeName.ToString(), simpleExtension);
  767.                 }
  768.                 else {
  769.                     complexType.SetBaseSchemaType(bto);
  770.                     complexType.SetDatatype(bto.Datatype);
  771.                 }
  772.                 baseType = bto as XmlSchemaComplexType;
  773.             }
  774.             if (baseType != null) {
  775.                 if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0) {
  776.                     SendValidationEvent(Res.Sch_BaseFinalExtension, complexType);
  777.                 }
  778.                 if (baseType.ContentType != XmlSchemaContentType.TextOnly) {
  779.                     SendValidationEvent(Res.Sch_NotSimpleContent, complexType);
  780.                 }
  781.             }
  782.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Extension);
  783.             CompileLocalAttributes(baseType, complexType, simpleExtension.Attributes, simpleExtension.AnyAttribute, XmlSchemaDerivationMethod.Extension);
  784.         }
  785.        
  786.         private void CompileSimpleContentRestriction(XmlSchemaComplexType complexType, XmlSchemaSimpleContentRestriction simpleRestriction)
  787.         {
  788.             XmlSchemaComplexType baseType = null;
  789.             XmlSchemaDatatype datatype = null;
  790.             if (complexType.Redefined != null && simpleRestriction.BaseTypeName == complexType.Redefined.QualifiedName) {
  791.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  792.                 CompileComplexType(baseType);
  793.                 datatype = baseType.Datatype;
  794.             }
  795.             else {
  796.                 baseType = GetComplexType(simpleRestriction.BaseTypeName);
  797.                 if (baseType == null) {
  798.                     SendValidationEvent(Res.Sch_UndefBaseRestriction, simpleRestriction.BaseTypeName.ToString(), simpleRestriction);
  799.                     return;
  800.                 }
  801.                 if (baseType.ContentType == XmlSchemaContentType.TextOnly) {
  802.                     if (simpleRestriction.BaseType == null) {
  803.                         datatype = baseType.Datatype;
  804.                         //There is a bug here. Need to check if simpleRestriction has facets.
  805.                         //If yes, Need tp apply these facets as well.
  806.                     }
  807.                     else {
  808.                         CompileSimpleType(simpleRestriction.BaseType);
  809.                         if (!XmlSchemaType.IsDerivedFromDatatype(simpleRestriction.BaseType.Datatype, baseType.Datatype, XmlSchemaDerivationMethod.None)) {
  810.                             SendValidationEvent(Res.Sch_DerivedNotFromBase, simpleRestriction);
  811.                         }
  812.                         datatype = simpleRestriction.BaseType.Datatype;
  813.                     }
  814.                 }
  815.                 else if (baseType.ContentType == XmlSchemaContentType.Mixed && baseType.ElementDecl.ContentValidator.IsEmptiable) {
  816.                     if (simpleRestriction.BaseType != null) {
  817.                         CompileSimpleType(simpleRestriction.BaseType);
  818.                         complexType.SetBaseSchemaType(simpleRestriction.BaseType);
  819.                         datatype = simpleRestriction.BaseType.Datatype;
  820.                     }
  821.                     else {
  822.                         SendValidationEvent(Res.Sch_NeedSimpleTypeChild, simpleRestriction);
  823.                     }
  824.                 }
  825.                 else {
  826.                     SendValidationEvent(Res.Sch_NotSimpleContent, complexType);
  827.                 }
  828.             }
  829.             if (baseType != null && baseType.ElementDecl != null) {
  830.                 if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
  831.                     SendValidationEvent(Res.Sch_BaseFinalRestriction, complexType);
  832.                 }
  833.             }
  834.             if (baseType != null) {
  835.                 complexType.SetBaseSchemaType(baseType);
  836.             }
  837.             if (datatype != null) {
  838.                 try {
  839.                     complexType.SetDatatype(datatype.DeriveByRestriction(simpleRestriction.Facets, NameTable, complexType));
  840.                 }
  841.                 catch (XmlSchemaException e) {
  842.                     if (e.SourceSchemaObject == null) {
  843.                         e.SetSource(complexType);
  844.                     }
  845.                     SendValidationEvent(e);
  846.                     complexType.SetDatatype(DatatypeImplementation.AnySimpleType.Datatype);
  847.                 }
  848.             }
  849.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  850.             CompileLocalAttributes(baseType, complexType, simpleRestriction.Attributes, simpleRestriction.AnyAttribute, XmlSchemaDerivationMethod.Restriction);
  851.         }
  852.        
  853.         private void CompileComplexContentExtension(XmlSchemaComplexType complexType, XmlSchemaComplexContent complexContent, XmlSchemaComplexContentExtension complexExtension)
  854.         {
  855.             XmlSchemaComplexType baseType = null;
  856.             if (complexType.Redefined != null && complexExtension.BaseTypeName == complexType.Redefined.QualifiedName) {
  857.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  858.                 CompileComplexType(baseType);
  859.             }
  860.             else {
  861.                 baseType = GetComplexType(complexExtension.BaseTypeName);
  862.                 if (baseType == null) {
  863.                     SendValidationEvent(Res.Sch_UndefBaseExtension, complexExtension.BaseTypeName.ToString(), complexExtension);
  864.                     return;
  865.                 }
  866.             }
  867.             if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Extension) != 0) {
  868.                 SendValidationEvent(Res.Sch_BaseFinalExtension, complexType);
  869.             }
  870.             CompileLocalAttributes(baseType, complexType, complexExtension.Attributes, complexExtension.AnyAttribute, XmlSchemaDerivationMethod.Extension);
  871.            
  872.             XmlSchemaParticle baseParticle = baseType.ContentTypeParticle;
  873.             XmlSchemaParticle extendedParticle = CannonicalizeParticle(complexExtension.Particle, true);
  874.             if (baseParticle != XmlSchemaParticle.Empty) {
  875.                 if (extendedParticle != XmlSchemaParticle.Empty) {
  876.                     XmlSchemaSequence compiledParticle = new XmlSchemaSequence();
  877.                     compiledParticle.Items.Add(baseParticle);
  878.                     compiledParticle.Items.Add(extendedParticle);
  879.                     complexType.SetContentTypeParticle(CompileContentTypeParticle(compiledParticle));
  880.                 }
  881.                 else {
  882.                     complexType.SetContentTypeParticle(baseParticle);
  883.                 }
  884.             }
  885.             else {
  886.                 complexType.SetContentTypeParticle(extendedParticle);
  887.             }
  888.             XmlSchemaContentType contentType = GetSchemaContentType(complexType, complexContent, extendedParticle);
  889.             if (contentType == XmlSchemaContentType.Empty) {
  890.                 //Derived content type is empty, Get ContentType from base
  891.                 contentType = baseType.ContentType;
  892.             }
  893.             complexType.SetContentType(contentType);
  894.            
  895.             if (baseType.ContentType != XmlSchemaContentType.Empty && complexType.ContentType != baseType.ContentType) {
  896.                 //If base is empty, do not check
  897.                 SendValidationEvent(Res.Sch_DifContentType, complexType);
  898.                 return;
  899.             }
  900.             complexType.SetBaseSchemaType(baseType);
  901.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Extension);
  902.         }
  903.        
  904.         private void CompileComplexContentRestriction(XmlSchemaComplexType complexType, XmlSchemaComplexContent complexContent, XmlSchemaComplexContentRestriction complexRestriction)
  905.         {
  906.             XmlSchemaComplexType baseType = null;
  907.             if (complexType.Redefined != null && complexRestriction.BaseTypeName == complexType.Redefined.QualifiedName) {
  908.                 baseType = (XmlSchemaComplexType)complexType.Redefined;
  909.                 CompileComplexType(baseType);
  910.             }
  911.             else {
  912.                 baseType = GetComplexType(complexRestriction.BaseTypeName);
  913.                 if (baseType == null) {
  914.                     SendValidationEvent(Res.Sch_UndefBaseRestriction, complexRestriction.BaseTypeName.ToString(), complexRestriction);
  915.                     return;
  916.                 }
  917.             }
  918.             complexType.SetBaseSchemaType(baseType);
  919.             if ((baseType.FinalResolved & XmlSchemaDerivationMethod.Restriction) != 0) {
  920.                 SendValidationEvent(Res.Sch_BaseFinalRestriction, complexType);
  921.             }
  922.             CompileLocalAttributes(baseType, complexType, complexRestriction.Attributes, complexRestriction.AnyAttribute, XmlSchemaDerivationMethod.Restriction);
  923.            
  924.             complexType.SetContentTypeParticle(CompileContentTypeParticle(complexRestriction.Particle));
  925.             XmlSchemaContentType derivedContentType = GetSchemaContentType(complexType, complexContent, complexType.ContentTypeParticle);
  926.             complexType.SetContentType(derivedContentType);
  927.             switch (derivedContentType) {
  928.                 case XmlSchemaContentType.Empty:
  929.                     if (baseType.ElementDecl != null && !baseType.ElementDecl.ContentValidator.IsEmptiable) {
  930.                         //base is either TextOnly or its ElementOnly/Mixed and not emptiable
  931.                         SendValidationEvent(Res.Sch_InvalidContentRestrictionDetailed, Res.GetString(Res.Sch_InvalidBaseToEmpty), complexType);
  932.                     }
  933.                     break;
  934.                 case XmlSchemaContentType.Mixed:
  935.                    
  936.                     if (baseType.ContentType != XmlSchemaContentType.Mixed) {
  937.                         SendValidationEvent(Res.Sch_InvalidContentRestrictionDetailed, Res.GetString(Res.Sch_InvalidBaseToMixed), complexType);
  938.                     }
  939.                     break;
  940.             }
  941.             complexType.SetDerivedBy(XmlSchemaDerivationMethod.Restriction);
  942.         }
  943.        
  944.         private void CheckParticleDerivation(XmlSchemaComplexType complexType)
  945.         {
  946.             XmlSchemaComplexType baseType = complexType.BaseXmlSchemaType as XmlSchemaComplexType;
  947.             restrictionErrorMsg = null;
  948.             if (baseType != null && baseType != XmlSchemaComplexType.AnyType && complexType.DerivedBy == XmlSchemaDerivationMethod.Restriction) {
  949.                 XmlSchemaParticle derivedParticle = CannonicalizePointlessRoot(complexType.ContentTypeParticle);
  950.                 XmlSchemaParticle baseParticle = CannonicalizePointlessRoot(baseType.ContentTypeParticle);
  951.                 if (!IsValidRestriction(derivedParticle, baseParticle)) {
  952.                     #if DEBUG
  953.                     if (complexType.ContentTypeParticle != null && baseType.ContentTypeParticle != null) {
  954.                         string position = string.Empty;
  955.                         if (complexType.SourceUri != null) {
  956.                             position = " in " + complexType.SourceUri + "(" + complexType.LineNumber + ", " + complexType.LinePosition + ")";
  957.                         }
  958.                         Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType content restriction" + position);
  959.                         Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpContentModel(baseType.ContentTypeParticle));
  960.                         Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpContentModel(complexType.ContentTypeParticle));
  961.                     }
  962.                     #endif
  963.                     if (restrictionErrorMsg != null) {
  964.                         SendValidationEvent(Res.Sch_InvalidParticleRestrictionDetailed, restrictionErrorMsg, complexType);
  965.                     }
  966.                     else {
  967.                         SendValidationEvent(Res.Sch_InvalidParticleRestriction, complexType);
  968.                     }
  969.                 }
  970.             }
  971.             else if (baseType == XmlSchemaComplexType.AnyType) {
  972.                 //The complex type itself is not explicitly derived by restriction but it could have local elements which have anonymous types that are derived by restriction
  973.                 foreach (XmlSchemaElement localElement in complexType.LocalElements.Values) {
  974.                     if (localElement.IsLocalTypeDerivationChecked) {
  975.                         //Element already checked
  976.                         continue;
  977.                     }
  978.                     XmlSchemaComplexType localComplexType = localElement.ElementSchemaType as XmlSchemaComplexType;
  979.                     if (localComplexType != null && localElement.SchemaTypeName == XmlQualifiedName.Empty && localElement.RefName == XmlQualifiedName.Empty) {
  980.                         //Only local elements
  981.                         localElement.IsLocalTypeDerivationChecked = true;
  982.                         //Not clearing this flag after recursion to make sure this check is not repeated for multiple references of the same local element (through group refs)
  983.                         CheckParticleDerivation(localComplexType);
  984.                     }
  985.                 }
  986.             }
  987.         }
  988.        
  989.         private void CheckParticleDerivation(XmlSchemaParticle derivedParticle, XmlSchemaParticle baseParticle)
  990.         {
  991.             restrictionErrorMsg = null;
  992.             derivedParticle = CannonicalizePointlessRoot(derivedParticle);
  993.             baseParticle = CannonicalizePointlessRoot(baseParticle);
  994.             if (!IsValidRestriction(derivedParticle, baseParticle)) {
  995.                 if (restrictionErrorMsg != null) {
  996.                     SendValidationEvent(Res.Sch_InvalidParticleRestrictionDetailed, restrictionErrorMsg, derivedParticle);
  997.                 }
  998.                 else {
  999.                     SendValidationEvent(Res.Sch_InvalidParticleRestriction, derivedParticle);
  1000.                 }
  1001.             }
  1002.         }
  1003.        
  1004.         private XmlSchemaParticle CompileContentTypeParticle(XmlSchemaParticle particle)
  1005.         {
  1006.             XmlSchemaParticle ctp = CannonicalizeParticle(particle, true);
  1007.             XmlSchemaChoice choice = ctp as XmlSchemaChoice;
  1008.             if (choice != null && choice.Items.Count == 0) {
  1009.                 if (choice.MinOccurs != decimal.Zero) {
  1010.                     SendValidationEvent(Res.Sch_EmptyChoice, choice, XmlSeverityType.Warning);
  1011.                 }
  1012.                 return XmlSchemaParticle.Empty;
  1013.             }
  1014.             return ctp;
  1015.         }
  1016.        
  1017.         private XmlSchemaParticle CannonicalizeParticle(XmlSchemaParticle particle, bool root)
  1018.         {
  1019.             if (particle == null || particle.IsEmpty) {
  1020.                 return XmlSchemaParticle.Empty;
  1021.             }
  1022.             else if (particle is XmlSchemaElement) {
  1023.                 //return CannonicalizeElement((XmlSchemaElement)particle, substitution);
  1024.                 return particle;
  1025.             }
  1026.             else if (particle is XmlSchemaGroupRef) {
  1027.                 return CannonicalizeGroupRef((XmlSchemaGroupRef)particle, root);
  1028.             }
  1029.             else if (particle is XmlSchemaAll) {
  1030.                 return CannonicalizeAll((XmlSchemaAll)particle, root);
  1031.             }
  1032.             else if (particle is XmlSchemaChoice) {
  1033.                 return CannonicalizeChoice((XmlSchemaChoice)particle, root);
  1034.             }
  1035.             else if (particle is XmlSchemaSequence) {
  1036.                 return CannonicalizeSequence((XmlSchemaSequence)particle, root);
  1037.             }
  1038.             else {
  1039.                 return particle;
  1040.             }
  1041.         }
  1042.        
  1043.         private XmlSchemaParticle CannonicalizeElement(XmlSchemaElement element)
  1044.         {
  1045.             if (!element.RefName.IsEmpty && (element.ElementDecl.Block & XmlSchemaDerivationMethod.Substitution) == 0) {
  1046.                 XmlSchemaSubstitutionGroup substitutionGroup = (XmlSchemaSubstitutionGroup)examplars[element.QualifiedName];
  1047.                 if (substitutionGroup == null) {
  1048.                     return element;
  1049.                 }
  1050.                 else {
  1051.                     XmlSchemaChoice choice = new XmlSchemaChoice();
  1052.                     foreach (XmlSchemaElement elem in substitutionGroup.Members) {
  1053.                         choice.Items.Add(elem);
  1054.                     }
  1055.                     choice.MinOccurs = element.MinOccurs;
  1056.                     choice.MaxOccurs = element.MaxOccurs;
  1057.                     CopyPosition(choice, element, false);
  1058.                     return choice;
  1059.                 }
  1060.             }
  1061.             else {
  1062.                 return element;
  1063.             }
  1064.         }
  1065.        
  1066.         private XmlSchemaParticle CannonicalizeGroupRef(XmlSchemaGroupRef groupRef, bool root)
  1067.         {
  1068.             XmlSchemaGroup group;
  1069.             if (groupRef.Redefined != null) {
  1070.                 group = groupRef.Redefined;
  1071.             }
  1072.             else {
  1073.                 group = (XmlSchemaGroup)groups[groupRef.RefName];
  1074.             }
  1075.             if (group == null) {
  1076.                 SendValidationEvent(Res.Sch_UndefGroupRef, groupRef.RefName.ToString(), groupRef);
  1077.                 return XmlSchemaParticle.Empty;
  1078.             }
  1079.             if (group.CanonicalParticle == null) {
  1080.                 CompileGroup(group);
  1081.             }
  1082.             if (group.CanonicalParticle == XmlSchemaParticle.Empty) {
  1083.                 return XmlSchemaParticle.Empty;
  1084.             }
  1085.             XmlSchemaGroupBase groupBase = (XmlSchemaGroupBase)group.CanonicalParticle;
  1086.             if (groupBase is XmlSchemaAll) {
  1087.                 if (!root) {
  1088.                     SendValidationEvent(Res.Sch_AllRefNotRoot, "", groupRef);
  1089.                     return XmlSchemaParticle.Empty;
  1090.                 }
  1091.                 if (groupRef.MinOccurs > decimal.One || groupRef.MaxOccurs != decimal.One) {
  1092.                     SendValidationEvent(Res.Sch_AllRefMinMax, groupRef);
  1093.                     return XmlSchemaParticle.Empty;
  1094.                 }
  1095.             }
  1096.             else if (groupBase is XmlSchemaChoice && groupBase.Items.Count == 0) {
  1097.                 if (groupRef.MinOccurs != decimal.Zero) {
  1098.                     SendValidationEvent(Res.Sch_EmptyChoice, groupRef, XmlSeverityType.Warning);
  1099.                 }
  1100.                 return XmlSchemaParticle.Empty;
  1101.             }
  1102.             XmlSchemaGroupBase groupRefBase = ((groupBase is XmlSchemaSequence) ? (XmlSchemaGroupBase)new XmlSchemaSequence() : (groupBase is XmlSchemaChoice) ? (XmlSchemaGroupBase)new XmlSchemaChoice() : (XmlSchemaGroupBase)new XmlSchemaAll());
  1103.             groupRefBase.MinOccurs = groupRef.MinOccurs;
  1104.             groupRefBase.MaxOccurs = groupRef.MaxOccurs;
  1105.             groupRefBase.LineNumber = groupRef.LineNumber;
  1106.             groupRefBase.LinePosition = groupRef.LinePosition;
  1107.            
  1108.             foreach (XmlSchemaParticle particle in groupBase.Items) {
  1109.                 groupRefBase.Items.Add(particle);
  1110.             }
  1111.             groupRef.SetParticle(groupRefBase);
  1112.             return groupRefBase;
  1113.         }
  1114.        
  1115.         private XmlSchemaParticle CannonicalizeAll(XmlSchemaAll all, bool root)
  1116.         {
  1117.             if (all.Items.Count > 0) {
  1118.                 XmlSchemaAll newAll = new XmlSchemaAll();
  1119.                 newAll.MinOccurs = all.MinOccurs;
  1120.                 newAll.MaxOccurs = all.MaxOccurs;
  1121.                 CopyPosition(newAll, all, true);
  1122.                 foreach (XmlSchemaElement e in all.Items) {
  1123.                     XmlSchemaParticle p = CannonicalizeParticle(e, false);
  1124.                     if (p != XmlSchemaParticle.Empty) {
  1125.                         newAll.Items.Add(p);
  1126.                     }
  1127.                 }
  1128.                 all = newAll;
  1129.             }
  1130.             if (all.Items.Count == 0) {
  1131.                 return XmlSchemaParticle.Empty;
  1132.             }
  1133.             else if (!root) {
  1134.                 SendValidationEvent(Res.Sch_NotAllAlone, all);
  1135.                 return XmlSchemaParticle.Empty;
  1136.             }
  1137.             else {
  1138.                 return all;
  1139.             }
  1140.         }
  1141.        
  1142.         private XmlSchemaParticle CannonicalizeChoice(XmlSchemaChoice choice, bool root)
  1143.         {
  1144.             XmlSchemaChoice oldChoice = choice;
  1145.             if (choice.Items.Count > 0) {
  1146.                 XmlSchemaChoice newChoice = new XmlSchemaChoice();
  1147.                 newChoice.MinOccurs = choice.MinOccurs;
  1148.                 newChoice.MaxOccurs = choice.MaxOccurs;
  1149.                 CopyPosition(newChoice, choice, true);
  1150.                 foreach (XmlSchemaParticle p in choice.Items) {
  1151.                     XmlSchemaParticle p1 = CannonicalizeParticle(p, false);
  1152.                     if (p1 != XmlSchemaParticle.Empty) {
  1153.                         if (p1.MinOccurs == decimal.One && p1.MaxOccurs == decimal.One && p1 is XmlSchemaChoice) {
  1154.                             foreach (XmlSchemaParticle p2 in ((XmlSchemaChoice)p1).Items) {
  1155.                                 newChoice.Items.Add(p2);
  1156.                             }
  1157.                         }
  1158.                         else {
  1159.                             newChoice.Items.Add(p1);
  1160.                         }
  1161.                     }
  1162.                 }
  1163.                 choice = newChoice;
  1164.             }
  1165.             if (!root && choice.Items.Count == 0) {
  1166.                 if (choice.MinOccurs != decimal.Zero) {
  1167.                     SendValidationEvent(Res.Sch_EmptyChoice, oldChoice, XmlSeverityType.Warning);
  1168.                 }
  1169.                 return XmlSchemaParticle.Empty;
  1170.             }
  1171.             else if (!root && choice.Items.Count == 1 && choice.MinOccurs == decimal.One && choice.MaxOccurs == decimal.One) {
  1172.                 return (XmlSchemaParticle)choice.Items[0];
  1173.             }
  1174.             else {
  1175.                 return choice;
  1176.             }
  1177.         }
  1178.        
  1179.         private XmlSchemaParticle CannonicalizeSequence(XmlSchemaSequence sequence, bool root)
  1180.         {
  1181.             if (sequence.Items.Count > 0) {
  1182.                 XmlSchemaSequence newSequence = new XmlSchemaSequence();
  1183.                 newSequence.MinOccurs = sequence.MinOccurs;
  1184.                 newSequence.MaxOccurs = sequence.MaxOccurs;
  1185.                 CopyPosition(newSequence, sequence, true);
  1186.                 foreach (XmlSchemaParticle p in sequence.Items) {
  1187.                     XmlSchemaParticle p1 = CannonicalizeParticle(p, false);
  1188.                     if (p1 != XmlSchemaParticle.Empty) {
  1189.                         if (p1.MinOccurs == decimal.One && p1.MaxOccurs == decimal.One && p1 is XmlSchemaSequence) {
  1190.                             foreach (XmlSchemaParticle p2 in ((XmlSchemaSequence)p1).Items) {
  1191.                                 newSequence.Items.Add(p2);
  1192.                             }
  1193.                         }
  1194.                         else {
  1195.                             newSequence.Items.Add(p1);
  1196.                         }
  1197.                     }
  1198.                 }
  1199.                 sequence = newSequence;
  1200.             }
  1201.             if (sequence.Items.Count == 0) {
  1202.                 return XmlSchemaParticle.Empty;
  1203.             }
  1204.             else if (!root && sequence.Items.Count == 1 && sequence.MinOccurs == decimal.One && sequence.MaxOccurs == decimal.One) {
  1205.                 return (XmlSchemaParticle)sequence.Items[0];
  1206.             }
  1207.             else {
  1208.                 return sequence;
  1209.             }
  1210.         }
  1211.        
  1212.         private XmlSchemaParticle CannonicalizePointlessRoot(XmlSchemaParticle particle)
  1213.         {
  1214.             if (particle == null) {
  1215.                 return null;
  1216.             }
  1217.             XmlSchemaSequence xss;
  1218.             XmlSchemaChoice xsc;
  1219.             XmlSchemaAll xsa;
  1220.             decimal one = decimal.One;
  1221.             if ((xss = (particle as XmlSchemaSequence)) != null) {
  1222.                 XmlSchemaObjectCollection items = xss.Items;
  1223.                 int count = items.Count;
  1224.                 if (count == 1) {
  1225.                     if (xss.MinOccurs == one && xss.MaxOccurs == one) {
  1226.                         return (XmlSchemaParticle)items[0];
  1227.                     }
  1228.                 }
  1229.             }
  1230.             else if ((xsc = (particle as XmlSchemaChoice)) != null) {
  1231.                 XmlSchemaObjectCollection items = xsc.Items;
  1232.                 int count = items.Count;
  1233.                 if (count == 1) {
  1234.                     if (xsc.MinOccurs == one && xsc.MaxOccurs == one) {
  1235.                         return (XmlSchemaParticle)items[0];
  1236.                     }
  1237.                 }
  1238.                 else if (count == 0) {
  1239.                     return XmlSchemaParticle.Empty;
  1240.                 }
  1241.             }
  1242.             else if ((xsa = (particle as XmlSchemaAll)) != null) {
  1243.                 XmlSchemaObjectCollection items = xsa.Items;
  1244.                 int count = items.Count;
  1245.                 if (count == 1) {
  1246.                     if (xsa.MinOccurs == one && xsa.MaxOccurs == one) {
  1247.                         return (XmlSchemaParticle)items[0];
  1248.                     }
  1249.                 }
  1250.             }
  1251.             return particle;
  1252.         }
  1253.        
  1254.         private bool IsValidRestriction(XmlSchemaParticle derivedParticle, XmlSchemaParticle baseParticle)
  1255.         {
  1256.             if (derivedParticle == baseParticle) {
  1257.                 return true;
  1258.             }
  1259.             else if (derivedParticle == null || derivedParticle == XmlSchemaParticle.Empty) {
  1260.                 return IsParticleEmptiable(baseParticle);
  1261.             }
  1262.             else if (baseParticle == null || baseParticle == XmlSchemaParticle.Empty) {
  1263.                 return false;
  1264.             }
  1265.             if (derivedParticle is XmlSchemaElement) {
  1266.                 //check for derived element being head of substitutionGroup
  1267.                 XmlSchemaElement derivedElem = (XmlSchemaElement)derivedParticle;
  1268.                 derivedParticle = CannonicalizeElement(derivedElem);
  1269.             }
  1270.             if (baseParticle is XmlSchemaElement) {
  1271.                 XmlSchemaElement baseElem = (XmlSchemaElement)baseParticle;
  1272.                 XmlSchemaParticle newBaseParticle;
  1273.                 newBaseParticle = CannonicalizeElement(baseElem);
  1274.                 if (newBaseParticle is XmlSchemaChoice) {
  1275.                     //Base Element is subs grp head.
  1276.                     return IsValidRestriction(derivedParticle, newBaseParticle);
  1277.                 }
  1278.                 else if (derivedParticle is XmlSchemaElement) {
  1279.                     return IsElementFromElement((XmlSchemaElement)derivedParticle, baseElem);
  1280.                 }
  1281.                 else {
  1282.                     restrictionErrorMsg = Res.GetString(Res.Sch_ForbiddenDerivedParticleForElem);
  1283.                     return false;
  1284.                 }
  1285.             }
  1286.             else if (baseParticle is XmlSchemaAny) {
  1287.                 if (derivedParticle is XmlSchemaElement) {
  1288.                     return IsElementFromAny((XmlSchemaElement)derivedParticle, (XmlSchemaAny)baseParticle);
  1289.                 }
  1290.                 else if (derivedParticle is XmlSchemaAny) {
  1291.                     return IsAnyFromAny((XmlSchemaAny)derivedParticle, (XmlSchemaAny)baseParticle);
  1292.                 }
  1293.                 else {
  1294.                     return IsGroupBaseFromAny((XmlSchemaGroupBase)derivedParticle, (XmlSchemaAny)baseParticle);
  1295.                 }
  1296.             }
  1297.             else if (baseParticle is XmlSchemaAll) {
  1298.                 if (derivedParticle is XmlSchemaElement) {
  1299.                     return IsElementFromGroupBase((XmlSchemaElement)derivedParticle, (XmlSchemaGroupBase)baseParticle);
  1300.                 }
  1301.                 else if (derivedParticle is XmlSchemaAll) {
  1302.                     if (IsGroupBaseFromGroupBase((XmlSchemaGroupBase)derivedParticle, (XmlSchemaGroupBase)baseParticle, true)) {
  1303.                         return true;
  1304.                     }
  1305.                 }
  1306.                 else if (derivedParticle is XmlSchemaSequence) {
  1307.                     if (IsSequenceFromAll((XmlSchemaSequence)derivedParticle, (XmlSchemaAll)baseParticle)) {
  1308.                         return true;
  1309.                     }
  1310.                     restrictionErrorMsg = Res.GetString(Res.Sch_SeqFromAll, derivedParticle.LineNumber.ToString(NumberFormatInfo.InvariantInfo), derivedParticle.LinePosition.ToString(NumberFormatInfo.InvariantInfo), baseParticle.LineNumber.ToString(NumberFormatInfo.InvariantInfo), baseParticle.LinePosition.ToString(NumberFormatInfo.InvariantInfo));
  1311.                 }
  1312.                 else if (derivedParticle is XmlSchemaChoice || derivedParticle is XmlSchemaAny) {
  1313.                     restrictionErrorMsg = Res.GetString(Res.Sch_ForbiddenDerivedParticleForAll);
  1314.                 }
  1315.                 return false;
  1316.             }
  1317.             else if (baseParticle is XmlSchemaChoice) {
  1318.                 if (derivedParticle is XmlSchemaElement) {
  1319.                     return IsElementFromGroupBase((XmlSchemaElement)derivedParticle, (XmlSchemaGroupBase)baseParticle);
  1320.                 }
  1321.                 else if (derivedParticle is XmlSchemaChoice) {
  1322.                     XmlSchemaChoice baseChoice = baseParticle as XmlSchemaChoice;
  1323.                     XmlSchemaChoice derivedChoice = derivedParticle as XmlSchemaChoice;
  1324.                     if (baseChoice.Parent == null || derivedChoice.Parent == null) {
  1325.                         //using parent property to indicate this choice was created on the fly for substitutionGroup
  1326.                         return IsChoiceFromChoiceSubstGroup(derivedChoice, baseChoice);
  1327.                     }
  1328.                     if (IsGroupBaseFromGroupBase(derivedChoice, baseChoice, false)) {
  1329.                         return true;
  1330.                     }
  1331.                 }
  1332.                 else if (derivedParticle is XmlSchemaSequence) {
  1333.                     if (IsSequenceFromChoice((XmlSchemaSequence)derivedParticle, (XmlSchemaChoice)baseParticle)) {
  1334.                         return true;
  1335.                     }
  1336.                     restrictionErrorMsg = Res.GetString(Res.Sch_SeqFromChoice, derivedParticle.LineNumber.ToString(NumberFormatInfo.InvariantInfo), derivedParticle.LinePosition.ToString(NumberFormatInfo.InvariantInfo), baseParticle.LineNumber.ToString(NumberFormatInfo.InvariantInfo), baseParticle.LinePosition.ToString(NumberFormatInfo.InvariantInfo));
  1337.                 }
  1338.                 else {
  1339.                     restrictionErrorMsg = Res.GetString(Res.Sch_ForbiddenDerivedParticleForChoice);
  1340.                 }
  1341.                 return false;
  1342.             }
  1343.             else if (baseParticle is XmlSchemaSequence) {
  1344.                 if (derivedParticle is XmlSchemaElement) {
  1345.                     return IsElementFromGroupBase((XmlSchemaElement)derivedParticle, (XmlSchemaGroupBase)baseParticle);
  1346.                 }
  1347.                 else if (derivedParticle is XmlSchemaSequence || (derivedParticle is XmlSchemaAll && ((XmlSchemaGroupBase)derivedParticle).Items.Count == 1)) {
  1348.                     if (IsGroupBaseFromGroupBase((XmlSchemaGroupBase)derivedParticle, (XmlSchemaGroupBase)baseParticle, true)) {
  1349.                         return true;
  1350.                     }
  1351.                 }
  1352.                 else {
  1353.                     restrictionErrorMsg = Res.GetString(Res.Sch_ForbiddenDerivedParticleForSeq);
  1354.                 }
  1355.                 return false;
  1356.             }
  1357.             else {
  1358.                 Debug.Assert(false);
  1359.             }
  1360.            
  1361.             return false;
  1362.         }
  1363.        
  1364.         private bool IsElementFromElement(XmlSchemaElement derivedElement, XmlSchemaElement baseElement)
  1365.         {
  1366.             if (!((derivedElement.QualifiedName == baseElement.QualifiedName) && (baseElement.IsNillable || !derivedElement.IsNillable) && IsValidOccurrenceRangeRestriction(derivedElement, baseElement) && (baseElement.FixedValue == null || IsFixedEqual(baseElement.ElementDecl, derivedElement.ElementDecl)) && ((derivedElement.ElementDecl.Block | baseElement.ElementDecl.Block) == derivedElement.ElementDecl.Block) && (derivedElement.ElementSchemaType != null) && (baseElement.ElementSchemaType != null) && XmlSchemaType.IsDerivedFrom(derivedElement.ElementSchemaType, baseElement.ElementSchemaType, ~(XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.List | XmlSchemaDerivationMethod.Union)))) {
  1367.                
  1368.                 restrictionErrorMsg = Res.GetString(Res.Sch_ElementFromElement, derivedElement.QualifiedName, baseElement.QualifiedName);
  1369.                 return false;
  1370.             }
  1371.             return true;
  1372.         }
  1373.        
  1374.         private bool IsElementFromAny(XmlSchemaElement derivedElement, XmlSchemaAny baseAny)
  1375.         {
  1376.             if (!baseAny.Allows(derivedElement.QualifiedName)) {
  1377.                 restrictionErrorMsg = Res.GetString(Res.Sch_ElementFromAnyRule1, derivedElement.QualifiedName.ToString());
  1378.                 return false;
  1379.             }
  1380.             if (!IsValidOccurrenceRangeRestriction(derivedElement, baseAny)) {
  1381.                 restrictionErrorMsg = Res.GetString(Res.Sch_ElementFromAnyRule2, derivedElement.QualifiedName.ToString());
  1382.                 return false;
  1383.             }
  1384.             return true;
  1385.         }
  1386.        
  1387.         private bool IsAnyFromAny(XmlSchemaAny derivedAny, XmlSchemaAny baseAny)
  1388.         {
  1389.             if (!IsValidOccurrenceRangeRestriction(derivedAny, baseAny)) {
  1390.                 restrictionErrorMsg = Res.GetString(Res.Sch_AnyFromAnyRule1);
  1391.                 return false;
  1392.             }
  1393.             if (!NamespaceList.IsSubset(derivedAny.NamespaceList, baseAny.NamespaceList)) {
  1394.                 restrictionErrorMsg = Res.GetString(Res.Sch_AnyFromAnyRule2);
  1395.                 return false;
  1396.             }
  1397.             if ((int)derivedAny.ProcessContentsCorrect < (int)baseAny.ProcessContentsCorrect) {
  1398.                 restrictionErrorMsg = Res.GetString(Res.Sch_AnyFromAnyRule3);
  1399.                 return false;
  1400.             }
  1401.             return true;
  1402.         }
  1403.        
  1404.         private bool IsGroupBaseFromAny(XmlSchemaGroupBase derivedGroupBase, XmlSchemaAny baseAny)
  1405.         {
  1406.             decimal minOccurs;
  1407.             decimal maxOccurs;
  1408.             CalculateEffectiveTotalRange(derivedGroupBase, out minOccurs, out maxOccurs);
  1409.             if (!IsValidOccurrenceRangeRestriction(minOccurs, maxOccurs, baseAny.MinOccurs, baseAny.MaxOccurs)) {
  1410.                 restrictionErrorMsg = Res.GetString(Res.Sch_GroupBaseFromAny2, derivedGroupBase.LineNumber.ToString(NumberFormatInfo.InvariantInfo), derivedGroupBase.LinePosition.ToString(NumberFormatInfo.InvariantInfo), baseAny.LineNumber.ToString(NumberFormatInfo.InvariantInfo), baseAny.LinePosition.ToString(NumberFormatInfo.InvariantInfo));
  1411.                 return false;
  1412.             }
  1413.             // eliminate occurrance range check
  1414.             string minOccursAny = baseAny.MinOccursString;
  1415.             baseAny.MinOccurs = decimal.Zero;
  1416.             foreach (XmlSchemaParticle p in derivedGroupBase.Items) {
  1417.                 if (!IsValidRestriction(p, baseAny)) {
  1418.                     restrictionErrorMsg = Res.GetString(Res.Sch_GroupBaseFromAny1);
  1419.                     baseAny.MinOccursString = minOccursAny;
  1420.                     return false;
  1421.                 }
  1422.             }
  1423.             baseAny.MinOccursString = minOccursAny;
  1424.             return true;
  1425.         }
  1426.        
  1427.         private bool IsElementFromGroupBase(XmlSchemaElement derivedElement, XmlSchemaGroupBase baseGroupBase)
  1428.         {
  1429.             if (baseGroupBase is XmlSchemaSequence) {
  1430.                 XmlSchemaSequence virtualSeq = new XmlSchemaSequence();
  1431.                 virtualSeq.MinOccurs = 1;
  1432.                 virtualSeq.MaxOccurs = 1;
  1433.                 virtualSeq.Items.Add(derivedElement);
  1434.                 if (IsGroupBaseFromGroupBase((XmlSchemaGroupBase)virtualSeq, baseGroupBase, true)) {
  1435.                     return true;
  1436.                 }
  1437.                 restrictionErrorMsg = Res.GetString(Res.Sch_ElementFromGroupBase1, derivedElement.QualifiedName.ToString(), derivedElement.LineNumber.ToString(NumberFormatInfo.InvariantInfo), derivedElement.LinePosition.ToString(NumberFormatInfo.InvariantInfo), baseGroupBase.LineNumber.ToString(NumberFormatInfo.InvariantInfo), baseGroupBase.LinePosition.ToString(NumberFormatInfo.InvariantInfo));
  1438.             }
  1439.             else if (baseGroupBase is XmlSchemaChoice) {
  1440.                 XmlSchemaChoice virtualChoice = new XmlSchemaChoice();
  1441.                 virtualChoice.MinOccurs = 1;
  1442.                 virtualChoice.MaxOccurs = 1;
  1443.                 virtualChoice.Items.Add(derivedElement);
  1444.                 if (IsGroupBaseFromGroupBase((XmlSchemaGroupBase)virtualChoice, baseGroupBase, false)) {
  1445.                     return true;
  1446.                 }
  1447.                 restrictionErrorMsg = Res.GetString(Res.Sch_ElementFromGroupBase2, derivedElement.QualifiedName.ToString(), derivedElement.LineNumber.ToString(NumberFormatInfo.InvariantInfo), derivedElement.LinePosition.ToString(NumberFormatInfo.InvariantInfo), baseGroupBase.LineNumber.ToString(NumberFormatInfo.InvariantInfo), baseGroupBase.LinePosition.ToString(NumberFormatInfo.InvariantInfo));
  1448.             }
  1449.             else if (baseGroupBase is XmlSchemaAll) {
  1450.                 XmlSchemaAll virtualAll = new XmlSchemaAll();
  1451.                 virtualAll.MinOccurs = 1;
  1452.                 virtualAll.MaxOccurs = 1;
  1453.                 virtualAll.Items.Add(derivedElement);
  1454.                 if (IsGroupBaseFromGroupBase((XmlSchemaGroupBase)virtualAll, baseGroupBase, true)) {
  1455.                     return true;
  1456.                 }
  1457.                 restrictionErrorMsg = Res.GetString(Res.Sch_ElementFromGroupBase3, derivedElement.QualifiedName.ToString(), derivedElement.LineNumber.ToString(NumberFormatInfo.InvariantInfo), derivedElement.LinePosition.ToString(NumberFormatInfo.InvariantInfo), baseGroupBase.LineNumber.ToString(NumberFormatInfo.InvariantInfo), baseGroupBase.LinePosition.ToString(NumberFormatInfo.InvariantInfo));
  1458.             }
  1459.             return false;
  1460.         }
  1461.        
  1462.         private bool IsChoiceFromChoiceSubstGroup(XmlSchemaChoice derivedChoice, XmlSchemaChoice baseChoice)
  1463.         {
  1464.             if (!IsValidOccurrenceRangeRestriction(derivedChoice, baseChoice)) {
  1465.                 restrictionErrorMsg = Res.GetString(Res.Sch_GroupBaseRestRangeInvalid);
  1466.                 return false;
  1467.             }
  1468.             foreach (XmlSchemaParticle particle in derivedChoice.Items) {
  1469.                 if (GetMappingParticle(particle, baseChoice.Items) < 0) {
  1470.                     return false;
  1471.                 }
  1472.             }
  1473.             return true;
  1474.         }
  1475.        
  1476.         private bool IsGroupBaseFromGroupBase(XmlSchemaGroupBase derivedGroupBase, XmlSchemaGroupBase baseGroupBase, bool skipEmptableOnly)
  1477.         {
  1478.             if (!IsValidOccurrenceRangeRestriction(derivedGroupBase, baseGroupBase)) {
  1479.                 restrictionErrorMsg = Res.GetString(Res.Sch_GroupBaseRestRangeInvalid);
  1480.                 return false;
  1481.             }
  1482.             if (derivedGroupBase.Items.Count > baseGroupBase.Items.Count) {
  1483.                 restrictionErrorMsg = Res.GetString(Res.Sch_GroupBaseRestNoMap);
  1484.                 return false;
  1485.             }
  1486.             int count = 0;
  1487.             foreach (XmlSchemaParticle baseParticle in baseGroupBase.Items) {
  1488.                 if ((count < derivedGroupBase.Items.Count) && IsValidRestriction((XmlSchemaParticle)derivedGroupBase.Items[count], baseParticle)) {
  1489.                     count++;
  1490.                 }
  1491.                 else if (skipEmptableOnly && !IsParticleEmptiable(baseParticle)) {
  1492.                     if (restrictionErrorMsg == null) {
  1493.                         //If restriction failed on previous check, do not overwrite error
  1494.                         restrictionErrorMsg = Res.GetString(Res.Sch_GroupBaseRestNotEmptiable);
  1495.                     }
  1496.                     return false;
  1497.                 }
  1498.             }
  1499.             if (count < derivedGroupBase.Items.Count) {
  1500.                 return false;
  1501.             }
  1502.             return true;
  1503.         }
  1504.        
  1505.         private bool IsSequenceFromAll(XmlSchemaSequence derivedSequence, XmlSchemaAll baseAll)
  1506.         {
  1507.             if (!IsValidOccurrenceRangeRestriction(derivedSequence, baseAll) || derivedSequence.Items.Count > baseAll.Items.Count) {
  1508.                 return false;
  1509.             }
  1510.             BitSet map = new BitSet(baseAll.Items.Count);
  1511.             foreach (XmlSchemaParticle p in derivedSequence.Items) {
  1512.                 int i = GetMappingParticle(p, baseAll.Items);
  1513.                 if (i >= 0) {
  1514.                     if (map[i]) {
  1515.                         return false;
  1516.                     }
  1517.                     else {
  1518.                         map.Set(i);
  1519.                     }
  1520.                 }
  1521.                 else {
  1522.                     return false;
  1523.                 }
  1524.             }
  1525.             for (int i = 0; i < baseAll.Items.Count; i++) {
  1526.                 if (!map[i] && !IsParticleEmptiable((XmlSchemaParticle)baseAll.Items[i])) {
  1527.                     return false;
  1528.                 }
  1529.             }
  1530.             return true;
  1531.         }
  1532.        
  1533.         private bool IsSequenceFromChoice(XmlSchemaSequence derivedSequence, XmlSchemaChoice baseChoice)
  1534.         {
  1535.             decimal minOccurs;
  1536.             decimal maxOccurs;
  1537.             minOccurs = derivedSequence.MinOccurs * derivedSequence.Items.Count;
  1538.             if (derivedSequence.MaxOccurs == decimal.MaxValue) {
  1539.                 maxOccurs = decimal.MaxValue;
  1540.             }
  1541.             else {
  1542.                 maxOccurs = derivedSequence.MaxOccurs * derivedSequence.Items.Count;
  1543.             }
  1544.             if (!IsValidOccurrenceRangeRestriction(minOccurs, maxOccurs, baseChoice.MinOccurs, baseChoice.MaxOccurs) || derivedSequence.Items.Count > baseChoice.Items.Count) {
  1545.                 return false;
  1546.             }
  1547.             foreach (XmlSchemaParticle particle in derivedSequence.Items) {
  1548.                 if (GetMappingParticle(particle, baseChoice.Items) < 0)
  1549.                     return false;
  1550.             }
  1551.             return true;
  1552.         }
  1553.        
  1554.         private bool IsValidOccurrenceRangeRestriction(XmlSchemaParticle derivedParticle, XmlSchemaParticle baseParticle)
  1555.         {
  1556.             return IsValidOccurrenceRangeRestriction(derivedParticle.MinOccurs, derivedParticle.MaxOccurs, baseParticle.MinOccurs, baseParticle.MaxOccurs);
  1557.         }
  1558.        
  1559.         private bool IsValidOccurrenceRangeRestriction(decimal minOccurs, decimal maxOccurs, decimal baseMinOccurs, decimal baseMaxOccurs)
  1560.         {
  1561.             return (baseMinOccurs <= minOccurs) && (maxOccurs <= baseMaxOccurs);
  1562.         }
  1563.        
  1564.         private int GetMappingParticle(XmlSchemaParticle particle, XmlSchemaObjectCollection collection)
  1565.         {
  1566.             for (int i = 0; i < collection.Count; i++) {
  1567.                 if (IsValidRestriction(particle, (XmlSchemaParticle)collection[i]))
  1568.                     return i;
  1569.             }
  1570.             return -1;
  1571.         }
  1572.        
  1573.         private bool IsParticleEmptiable(XmlSchemaParticle particle)
  1574.         {
  1575.             decimal minOccurs;
  1576.             decimal maxOccurs;
  1577.             CalculateEffectiveTotalRange(particle, out minOccurs, out maxOccurs);
  1578.             return minOccurs == decimal.Zero;
  1579.         }
  1580.        
  1581.         private void CalculateEffectiveTotalRange(XmlSchemaParticle particle, out decimal minOccurs, out decimal maxOccurs)
  1582.         {
  1583.             if (particle is XmlSchemaElement || particle is XmlSchemaAny) {
  1584.                 minOccurs = particle.MinOccurs;
  1585.                 maxOccurs = particle.MaxOccurs;
  1586.             }
  1587.             else if (particle is XmlSchemaChoice) {
  1588.                 if (((XmlSchemaChoice)particle).Items.Count == 0) {
  1589.                     minOccurs = maxOccurs = decimal.Zero;
  1590.                 }
  1591.                 else {
  1592.                     minOccurs = decimal.MaxValue;
  1593.                     maxOccurs = decimal.Zero;
  1594.                     foreach (XmlSchemaParticle p in ((XmlSchemaChoice)particle).Items) {
  1595.                         decimal min;
  1596.                         decimal max;
  1597.                         CalculateEffectiveTotalRange(p, out min, out max);
  1598.                         if (min < minOccurs) {
  1599.                             minOccurs = min;
  1600.                         }
  1601.                         if (max > maxOccurs) {
  1602.                             maxOccurs = max;
  1603.                         }
  1604.                     }
  1605.                     minOccurs *= particle.MinOccurs;
  1606.                     if (maxOccurs != decimal.MaxValue) {
  1607.                         if (particle.MaxOccurs == decimal.MaxValue)
  1608.                             maxOccurs = decimal.MaxValue;
  1609.                         else
  1610.                             maxOccurs *= particle.MaxOccurs;
  1611.                     }
  1612.                 }
  1613.             }
  1614.             else {
  1615.                 XmlSchemaObjectCollection collection = ((XmlSchemaGroupBase)particle).Items;
  1616.                 if (collection.Count == 0) {
  1617.                     minOccurs = maxOccurs = decimal.Zero;
  1618.                 }
  1619.                 else {
  1620.                     minOccurs = 0;
  1621.                     maxOccurs = 0;
  1622.                     foreach (XmlSchemaParticle p in collection) {
  1623.                         decimal min;
  1624.                         decimal max;
  1625.                         CalculateEffectiveTotalRange(p, out min, out max);
  1626.                         minOccurs += min;
  1627.                         if (maxOccurs != decimal.MaxValue) {
  1628.                             if (max == decimal.MaxValue)
  1629.                                 maxOccurs = decimal.MaxValue;
  1630.                             else
  1631.                                 maxOccurs += max;
  1632.                         }
  1633.                     }
  1634.                     minOccurs *= particle.MinOccurs;
  1635.                     if (maxOccurs != decimal.MaxValue) {
  1636.                         if (particle.MaxOccurs == decimal.MaxValue)
  1637.                             maxOccurs = decimal.MaxValue;
  1638.                         else
  1639.                             maxOccurs *= particle.MaxOccurs;
  1640.                     }
  1641.                 }
  1642.             }
  1643.         }
  1644.        
  1645.         private void PushComplexType(XmlSchemaComplexType complexType)
  1646.         {
  1647.             this.complexTypeStack.Push(complexType);
  1648.         }
  1649.        
  1650.         private XmlSchemaContentType GetSchemaContentType(XmlSchemaComplexType complexType, XmlSchemaComplexContent complexContent, XmlSchemaParticle particle)
  1651.         {
  1652.             if ((complexContent != null && complexContent.IsMixed) || (complexContent == null && complexType.IsMixed)) {
  1653.                 return XmlSchemaContentType.Mixed;
  1654.             }
  1655.             else if (particle != null && !particle.IsEmpty) {
  1656.                 return XmlSchemaContentType.ElementOnly;
  1657.             }
  1658.             else {
  1659.                 return XmlSchemaContentType.Empty;
  1660.             }
  1661.         }
  1662.        
  1663.         private void CompileAttributeGroup(XmlSchemaAttributeGroup attributeGroup)
  1664.         {
  1665.             if (attributeGroup.IsProcessing) {
  1666.                 SendValidationEvent(Res.Sch_AttributeGroupCircularRef, attributeGroup);
  1667.                 return;
  1668.             }
  1669.             if (attributeGroup.AttributeUses.Count > 0) {
  1670.                 // already checked
  1671.                 return;
  1672.             }
  1673.             attributeGroup.IsProcessing = true;
  1674.             XmlSchemaAnyAttribute anyAttribute = attributeGroup.AnyAttribute;
  1675.            
  1676.             try {
  1677.                 foreach (XmlSchemaObject obj in attributeGroup.Attributes) {
  1678.                     if (obj is XmlSchemaAttribute) {
  1679.                         XmlSchemaAttribute attribute = (XmlSchemaAttribute)obj;
  1680.                         if (attribute.Use == XmlSchemaUse.Prohibited) {
  1681.                             continue;
  1682.                         }
  1683.                         CompileAttribute(attribute);
  1684.                         if (attributeGroup.AttributeUses[attribute.QualifiedName] == null) {
  1685.                             attributeGroup.AttributeUses.Add(attribute.QualifiedName, attribute);
  1686.                         }
  1687.                         else {
  1688.                             SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attribute);
  1689.                         }
  1690.                     }
  1691.                     else {
  1692.                         // XmlSchemaAttributeGroupRef
  1693.                         XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
  1694.                         XmlSchemaAttributeGroup attributeGroupResolved;
  1695.                         if (attributeGroup.Redefined != null && attributeGroupRef.RefName == attributeGroup.Redefined.QualifiedName) {
  1696.                             attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroup.Redefined;
  1697.                         }
  1698.                         else {
  1699.                             attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroups[attributeGroupRef.RefName];
  1700.                         }
  1701.                         if (attributeGroupResolved != null) {
  1702.                             CompileAttributeGroup(attributeGroupResolved);
  1703.                             foreach (XmlSchemaAttribute attribute in attributeGroupResolved.AttributeUses.Values) {
  1704.                                 if (attributeGroup.AttributeUses[attribute.QualifiedName] == null) {
  1705.                                     attributeGroup.AttributeUses.Add(attribute.QualifiedName, attribute);
  1706.                                 }
  1707.                                 else {
  1708.                                     SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attribute);
  1709.                                 }
  1710.                             }
  1711.                             anyAttribute = CompileAnyAttributeIntersection(anyAttribute, attributeGroupResolved.AttributeWildcard);
  1712.                         }
  1713.                         else {
  1714.                             SendValidationEvent(Res.Sch_UndefAttributeGroupRef, attributeGroupRef.RefName.ToString(), attributeGroupRef);
  1715.                         }
  1716.                     }
  1717.                 }
  1718.                 attributeGroup.AttributeWildcard = anyAttribute;
  1719.             }
  1720.             finally {
  1721.                 attributeGroup.IsProcessing = false;
  1722.             }
  1723.         }
  1724.        
  1725.         private void CompileLocalAttributes(XmlSchemaComplexType baseType, XmlSchemaComplexType derivedType, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, XmlSchemaDerivationMethod derivedBy)
  1726.         {
  1727.             XmlSchemaAnyAttribute baseAttributeWildcard = baseType != null ? baseType.AttributeWildcard : null;
  1728.             foreach (XmlSchemaObject obj in attributes) {
  1729.                 if (obj is XmlSchemaAttribute) {
  1730.                     XmlSchemaAttribute attribute = (XmlSchemaAttribute)obj;
  1731.                     if (attribute.Use != XmlSchemaUse.Prohibited) {
  1732.                         CompileAttribute(attribute);
  1733.                     }
  1734.                     if (attribute.Use != XmlSchemaUse.Prohibited || (attribute.Use == XmlSchemaUse.Prohibited && derivedBy == XmlSchemaDerivationMethod.Restriction && baseType != XmlSchemaComplexType.AnyType)) {
  1735.                        
  1736.                         if (derivedType.AttributeUses[attribute.QualifiedName] == null) {
  1737.                             derivedType.AttributeUses.Add(attribute.QualifiedName, attribute);
  1738.                         }
  1739.                         else {
  1740.                             SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attribute);
  1741.                         }
  1742.                     }
  1743.                     else {
  1744.                         SendValidationEvent(Res.Sch_AttributeIgnored, attribute.QualifiedName.ToString(), attribute, XmlSeverityType.Warning);
  1745.                     }
  1746.                    
  1747.                 }
  1748.                 else {
  1749.                     // is XmlSchemaAttributeGroupRef
  1750.                     XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
  1751.                     XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)attributeGroups[attributeGroupRef.RefName];
  1752.                     if (attributeGroup != null) {
  1753.                         CompileAttributeGroup(attributeGroup);
  1754.                         foreach (XmlSchemaAttribute attribute in attributeGroup.AttributeUses.Values) {
  1755.                             if (attribute.Use != XmlSchemaUse.Prohibited || (attribute.Use == XmlSchemaUse.Prohibited && derivedBy == XmlSchemaDerivationMethod.Restriction && baseType != XmlSchemaComplexType.AnyType)) {
  1756.                                 if (derivedType.AttributeUses[attribute.QualifiedName] == null) {
  1757.                                     derivedType.AttributeUses.Add(attribute.QualifiedName, attribute);
  1758.                                 }
  1759.                                 else {
  1760.                                     SendValidationEvent(Res.Sch_DupAttributeUse, attribute.QualifiedName.ToString(), attributeGroupRef);
  1761.                                 }
  1762.                             }
  1763.                             else {
  1764.                                 SendValidationEvent(Res.Sch_AttributeIgnored, attribute.QualifiedName.ToString(), attribute, XmlSeverityType.Warning);
  1765.                             }
  1766.                            
  1767.                         }
  1768.                         anyAttribute = CompileAnyAttributeIntersection(anyAttribute, attributeGroup.AttributeWildcard);
  1769.                     }
  1770.                     else {
  1771.                         SendValidationEvent(Res.Sch_UndefAttributeGroupRef, attributeGroupRef.RefName.ToString(), attributeGroupRef);
  1772.                     }
  1773.                 }
  1774.             }
  1775.            
  1776.             // check derivation rules
  1777.             if (baseType != null) {
  1778.                 if (derivedBy == XmlSchemaDerivationMethod.Extension) {
  1779.                     derivedType.SetAttributeWildcard(CompileAnyAttributeUnion(anyAttribute, baseAttributeWildcard));
  1780.                     foreach (XmlSchemaAttribute attributeBase in baseType.AttributeUses.Values) {
  1781.                         XmlSchemaAttribute attribute = (XmlSchemaAttribute)derivedType.AttributeUses[attributeBase.QualifiedName];
  1782.                         if (attribute == null) {
  1783.                             derivedType.AttributeUses.Add(attributeBase.QualifiedName, attributeBase);
  1784.                         }
  1785.                         else {
  1786.                             Debug.Assert(attribute.Use != XmlSchemaUse.Prohibited);
  1787.                             if (attributeBase.Use != XmlSchemaUse.Prohibited && attribute.AttributeSchemaType != attributeBase.AttributeSchemaType) {
  1788.                                 //Extension allows previously prohibited attributes to be re-added,
  1789.                                 SendValidationEvent(Res.Sch_InvalidAttributeExtension, attribute);
  1790.                             }
  1791.                         }
  1792.                     }
  1793.                 }
  1794.                 else {
  1795.                     // derivedBy == XmlSchemaDerivationMethod.Restriction
  1796.                     // Schema Component Constraint: Derivation Valid (Restriction, Complex)
  1797.                     if ((anyAttribute != null) && (baseAttributeWildcard == null || !XmlSchemaAnyAttribute.IsSubset(anyAttribute, baseAttributeWildcard) || !IsProcessContentsRestricted(baseType, anyAttribute, baseAttributeWildcard))) {
  1798.                         SendValidationEvent(Res.Sch_InvalidAnyAttributeRestriction, derivedType);
  1799.                     }
  1800.                     else {
  1801.                         derivedType.SetAttributeWildcard(anyAttribute);
  1802.                         //complete wildcard
  1803.                     }
  1804.                    
  1805.                     // Add form the base
  1806.                     foreach (XmlSchemaAttribute attributeBase in baseType.AttributeUses.Values) {
  1807.                         XmlSchemaAttribute attribute = (XmlSchemaAttribute)derivedType.AttributeUses[attributeBase.QualifiedName];
  1808.                         if (attribute == null) {
  1809.                             derivedType.AttributeUses.Add(attributeBase.QualifiedName, attributeBase);
  1810.                         }
  1811.                         else {
  1812.                             if (attributeBase.Use == XmlSchemaUse.Prohibited && attribute.Use != XmlSchemaUse.Prohibited) {
  1813.                                 #if DEBUG
  1814.                                 string position = string.Empty;
  1815.                                 if (derivedType.SourceUri != null) {
  1816.                                     position = " in " + derivedType.SourceUri + "(" + derivedType.LineNumber + ", " + derivedType.LinePosition + ")";
  1817.                                 }
  1818.                                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType attributes restriction" + position);
  1819.                                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpAttributes(baseType.AttributeUses, baseType.AttributeWildcard));
  1820.                                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpAttributes(derivedType.AttributeUses, derivedType.AttributeWildcard));
  1821.                                 #endif
  1822.                                 SendValidationEvent(Res.Sch_AttributeRestrictionProhibited, attribute);
  1823.                             }
  1824.                             else if (attributeBase.Use == XmlSchemaUse.Required && (attribute.Use != XmlSchemaUse.Required)) {
  1825.                                 //If base is required, derived should also be required
  1826.                                 SendValidationEvent(Res.Sch_AttributeUseInvalid, attribute);
  1827.                             }
  1828.                             else if (attribute.Use == XmlSchemaUse.Prohibited) {
  1829.                                 continue;
  1830.                             }
  1831.                             else if (attributeBase.AttributeSchemaType == null || attribute.AttributeSchemaType == null || !XmlSchemaType.IsDerivedFrom(attribute.AttributeSchemaType, attributeBase.AttributeSchemaType, XmlSchemaDerivationMethod.Empty)) {
  1832.                                 SendValidationEvent(Res.Sch_AttributeRestrictionInvalid, attribute);
  1833.                             }
  1834.                             else if (!IsFixedEqual(attributeBase.AttDef, attribute.AttDef)) {
  1835.                                 SendValidationEvent(Res.Sch_AttributeFixedInvalid, attribute);
  1836.                             }
  1837.                         }
  1838.                     }
  1839.                    
  1840.                     // Check additional ones are valid restriction of base's wildcard
  1841.                     foreach (XmlSchemaAttribute attribute in derivedType.AttributeUses.Values) {
  1842.                         XmlSchemaAttribute attributeBase = (XmlSchemaAttribute)baseType.AttributeUses[attribute.QualifiedName];
  1843.                         if (attributeBase != null) {
  1844.                             continue;
  1845.                         }
  1846.                         if (baseAttributeWildcard == null || !baseAttributeWildcard.Allows(attribute.QualifiedName)) {
  1847.                             #if DEBUG
  1848.                             string position = string.Empty;
  1849.                             if (derivedType.SourceUri != null) {
  1850.                                 position = " in " + derivedType.SourceUri + "(" + derivedType.LineNumber + ", " + derivedType.LinePosition + ")";
  1851.                             }
  1852.                             Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, "Invalid complexType attributes restriction" + position);
  1853.                             Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Base " + DumpAttributes(baseType.AttributeUses, baseType.AttributeWildcard));
  1854.                             Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceError, " Derived " + DumpAttributes(derivedType.AttributeUses, derivedType.AttributeWildcard));
  1855.                             #endif
  1856.                             SendValidationEvent(Res.Sch_AttributeRestrictionInvalidFromWildcard, attribute);
  1857.                         }
  1858.                     }
  1859.                 }
  1860.             }
  1861.             else {
  1862.                 derivedType.SetAttributeWildcard(anyAttribute);
  1863.             }
  1864.         }
  1865.        
  1866.         private void CheckAtrributeGroupRestriction(XmlSchemaAttributeGroup baseAttributeGroup, XmlSchemaAttributeGroup derivedAttributeGroup)
  1867.         {
  1868.             XmlSchemaAnyAttribute baseAnyAtt = baseAttributeGroup.AttributeWildcard;
  1869.             XmlSchemaAnyAttribute derivedAnyAtt = derivedAttributeGroup.AttributeWildcard;
  1870.            
  1871.             if ((derivedAnyAtt != null) && (baseAnyAtt == null || !XmlSchemaAnyAttribute.IsSubset(derivedAnyAtt, baseAnyAtt) || !IsProcessContentsRestricted(null, derivedAnyAtt, baseAnyAtt))) {
  1872.                 SendValidationEvent(Res.Sch_InvalidAnyAttributeRestriction, derivedAttributeGroup);
  1873.             }
  1874.             foreach (XmlSchemaAttribute attributeBase in baseAttributeGroup.AttributeUses.Values) {
  1875.                 XmlSchemaAttribute attribute = (XmlSchemaAttribute)derivedAttributeGroup.AttributeUses[attributeBase.QualifiedName];
  1876.                 if (attribute != null) {
  1877.                     if (attributeBase.Use == XmlSchemaUse.Prohibited && attribute.Use != XmlSchemaUse.Prohibited) {
  1878.                         SendValidationEvent(Res.Sch_AttributeRestrictionProhibited, attribute);
  1879.                     }
  1880.                     else if (attributeBase.Use == XmlSchemaUse.Required && attribute.Use != XmlSchemaUse.Required) {
  1881.                         SendValidationEvent(Res.Sch_AttributeUseInvalid, attribute);
  1882.                     }
  1883.                     else if (attribute.Use == XmlSchemaUse.Prohibited) {
  1884.                         //If derived att is prohibited, continue
  1885.                         continue;
  1886.                     }
  1887.                     else if (attributeBase.AttributeSchemaType == null || attribute.AttributeSchemaType == null || !XmlSchemaType.IsDerivedFrom(attribute.AttributeSchemaType, attributeBase.AttributeSchemaType, XmlSchemaDerivationMethod.Empty)) {
  1888.                         SendValidationEvent(Res.Sch_AttributeRestrictionInvalid, attribute);
  1889.                     }
  1890.                     else if (!IsFixedEqual(attributeBase.AttDef, attribute.AttDef)) {
  1891.                         SendValidationEvent(Res.Sch_AttributeFixedInvalid, attribute);
  1892.                     }
  1893.                 }
  1894.                 else if (attributeBase.Use == XmlSchemaUse.Required) {
  1895.                     SendValidationEvent(Res.Sch_NoDerivedAttribute, attributeBase.QualifiedName.ToString(), baseAttributeGroup.QualifiedName.ToString(), derivedAttributeGroup);
  1896.                 }
  1897.             }
  1898.             // Check additional ones are valid restriction of base's wildcard
  1899.             foreach (XmlSchemaAttribute attribute in derivedAttributeGroup.AttributeUses.Values) {
  1900.                 XmlSchemaAttribute attributeBase = (XmlSchemaAttribute)baseAttributeGroup.AttributeUses[attribute.QualifiedName];
  1901.                 if (attributeBase != null) {
  1902.                     continue;
  1903.                 }
  1904.                 if (baseAnyAtt == null || !baseAnyAtt.Allows(attribute.QualifiedName)) {
  1905.                     SendValidationEvent(Res.Sch_AttributeRestrictionInvalidFromWildcard, attribute);
  1906.                 }
  1907.             }
  1908.         }
  1909.        
  1910.         #if DEBUG
  1911.         private string DumpAttributes(XmlSchemaObjectTable attributeUses, XmlSchemaAnyAttribute attributeWildcard)
  1912.         {
  1913.             StringBuilder sb = new StringBuilder();
  1914.             sb.Append("[");
  1915.             bool first = true;
  1916.             foreach (XmlSchemaAttribute attribute in attributeUses.Values) {
  1917.                 if (attribute.Use != XmlSchemaUse.Prohibited) {
  1918.                     if (first) {
  1919.                         first = false;
  1920.                     }
  1921.                     else {
  1922.                         sb.Append(" ");
  1923.                     }
  1924.                     sb.Append(attribute.QualifiedName.Name);
  1925.                     if (attribute.Use == XmlSchemaUse.Optional || attribute.Use == XmlSchemaUse.None) {
  1926.                         sb.Append("?");
  1927.                     }
  1928.                 }
  1929.             }
  1930.             if (attributeWildcard != null) {
  1931.                 if (attributeUses.Count != 0) {
  1932.                     sb.Append(" ");
  1933.                 }
  1934.                 sb.Append("<");
  1935.                 sb.Append(attributeWildcard.NamespaceList.ToString());
  1936.                 sb.Append(">");
  1937.             }
  1938.             sb.Append("] - [");
  1939.             first = true;
  1940.             foreach (XmlSchemaAttribute attribute in attributeUses.Values) {
  1941.                 if (attribute.Use == XmlSchemaUse.Prohibited) {
  1942.                     if (first) {
  1943.                         first = false;
  1944.                     }
  1945.                     else {
  1946.                         sb.Append(" ");
  1947.                     }
  1948.                     sb.Append(attribute.QualifiedName.Name);
  1949.                 }
  1950.             }
  1951.             sb.Append("]");
  1952.             return sb.ToString();
  1953.         }
  1954.         #endif
  1955.        
  1956.         private bool IsProcessContentsRestricted(XmlSchemaComplexType baseType, XmlSchemaAnyAttribute derivedAttributeWildcard, XmlSchemaAnyAttribute baseAttributeWildcard)
  1957.         {
  1958.             if (baseType == XmlSchemaComplexType.AnyType) {
  1959.                 return true;
  1960.             }
  1961.             if ((int)derivedAttributeWildcard.ProcessContentsCorrect >= (int)baseAttributeWildcard.ProcessContentsCorrect) {
  1962.                 return true;
  1963.             }
  1964.             return false;
  1965.         }
  1966.        
  1967.         private XmlSchemaAnyAttribute CompileAnyAttributeUnion(XmlSchemaAnyAttribute a, XmlSchemaAnyAttribute b)
  1968.         {
  1969.             if (a == null) {
  1970.                 return b;
  1971.             }
  1972.             else if (b == null) {
  1973.                 return a;
  1974.             }
  1975.             else {
  1976.                 XmlSchemaAnyAttribute attribute = XmlSchemaAnyAttribute.Union(a, b, false);
  1977.                 //false is for v1Compatd
  1978.                 if (attribute == null) {
  1979.                     SendValidationEvent(Res.Sch_UnexpressibleAnyAttribute, a);
  1980.                 }
  1981.                 return attribute;
  1982.             }
  1983.            
  1984.         }
  1985.        
  1986.         private XmlSchemaAnyAttribute CompileAnyAttributeIntersection(XmlSchemaAnyAttribute a, XmlSchemaAnyAttribute b)
  1987.         {
  1988.             if (a == null) {
  1989.                 return b;
  1990.             }
  1991.             else if (b == null) {
  1992.                 return a;
  1993.             }
  1994.             else {
  1995.                 XmlSchemaAnyAttribute attribute = XmlSchemaAnyAttribute.Intersection(a, b, false);
  1996.                 //false is for v1Compat
  1997.                 if (attribute == null) {
  1998.                     SendValidationEvent(Res.Sch_UnexpressibleAnyAttribute, a);
  1999.                 }
  2000.                 return attribute;
  2001.             }
  2002.         }
  2003.        
  2004.         private void CompileAttribute(XmlSchemaAttribute xa)
  2005.         {
  2006.             if (xa.IsProcessing) {
  2007.                 SendValidationEvent(Res.Sch_AttributeCircularRef, xa);
  2008.                 return;
  2009.             }
  2010.             if (xa.AttDef != null) {
  2011.                 //already compiled?
  2012.                 return;
  2013.             }
  2014.             xa.IsProcessing = true;
  2015.             SchemaAttDef decl = null;
  2016.             try {
  2017.                 if (!xa.RefName.IsEmpty) {
  2018.                     XmlSchemaAttribute a = (XmlSchemaAttribute)attributes[xa.RefName];
  2019.                     if (a == null) {
  2020.                         throw new XmlSchemaException(Res.Sch_UndeclaredAttribute, xa.RefName.ToString(), xa);
  2021.                     }
  2022.                     CompileAttribute(a);
  2023.                     if (a.AttDef == null) {
  2024.                         throw new XmlSchemaException(Res.Sch_RefInvalidAttribute, xa.RefName.ToString(), xa);
  2025.                     }
  2026.                     decl = a.AttDef.Clone();
  2027.                     XmlSchemaDatatype datatype = decl.Datatype;
  2028.                    
  2029.                     if (datatype != null) {
  2030.                         if (a.FixedValue == null && a.DefaultValue == null) {
  2031.                             SetDefaultFixed(xa, decl);
  2032.                         }
  2033.                         else if (a.FixedValue != null) {
  2034.                             if (xa.DefaultValue != null) {
  2035.                                 throw new XmlSchemaException(Res.Sch_FixedDefaultInRef, xa.RefName.ToString(), xa);
  2036.                             }
  2037.                             else if (xa.FixedValue != null) {
  2038.                                 object refFixedValue = datatype.ParseValue(xa.FixedValue, NameTable, new SchemaNamespaceManager(xa), true);
  2039.                                 if (!datatype.IsEqual(decl.DefaultValueTyped, refFixedValue)) {
  2040.                                     throw new XmlSchemaException(Res.Sch_FixedInRef, xa.RefName.ToString(), xa);
  2041.                                 }
  2042.                             }
  2043.                         }
  2044.                     }
  2045.                     xa.SetAttributeType(a.AttributeSchemaType);
  2046.                 }
  2047.                 else {
  2048.                     decl = new SchemaAttDef(xa.QualifiedName, xa.Prefix);
  2049.                     if (xa.SchemaType != null) {
  2050.                         CompileSimpleType(xa.SchemaType);
  2051.                         xa.SetAttributeType(xa.SchemaType);
  2052.                         decl.SchemaType = xa.SchemaType;
  2053.                         decl.Datatype = xa.SchemaType.Datatype;
  2054.                     }
  2055.                     else if (!xa.SchemaTypeName.IsEmpty) {
  2056.                         XmlSchemaSimpleType simpleType = GetSimpleType(xa.SchemaTypeName);
  2057.                         if (simpleType != null) {
  2058.                             xa.SetAttributeType(simpleType);
  2059.                             decl.Datatype = simpleType.Datatype;
  2060.                             decl.SchemaType = simpleType;
  2061.                         }
  2062.                         else {
  2063.                             throw new XmlSchemaException(Res.Sch_UndeclaredSimpleType, xa.SchemaTypeName.ToString(), xa);
  2064.                         }
  2065.                     }
  2066.                     else {
  2067.                         decl.SchemaType = DatatypeImplementation.AnySimpleType;
  2068.                         decl.Datatype = DatatypeImplementation.AnySimpleType.Datatype;
  2069.                         xa.SetAttributeType(DatatypeImplementation.AnySimpleType);
  2070.                     }
  2071.                     //} //Removed this here since the following should be done only if RefName is Empty
  2072.                     if (decl.Datatype != null) {
  2073.                         decl.Datatype.VerifySchemaValid(notations, xa);
  2074.                     }
  2075.                     SetDefaultFixed(xa, decl);
  2076.                 }
  2077.                 //End of Else for !RefName.IsEmpty
  2078.                 decl.SchemaAttribute = xa;
  2079.                 //So this is available for PSVI
  2080.                 xa.AttDef = decl;
  2081.             }
  2082.             catch (XmlSchemaException e) {
  2083.                 if (e.SourceSchemaObject == null) {
  2084.                     e.SetSource(xa);
  2085.                 }
  2086.                 SendValidationEvent(e);
  2087.                 xa.AttDef = SchemaAttDef.Empty;
  2088.             }
  2089.             finally {
  2090.                 xa.IsProcessing = false;
  2091.             }
  2092.         }
  2093.        
  2094.         private void SetDefaultFixed(XmlSchemaAttribute xa, SchemaAttDef decl)
  2095.         {
  2096.             if (xa.DefaultValue != null || xa.FixedValue != null) {
  2097.                 if (xa.DefaultValue != null) {
  2098.                     decl.Presence = SchemaDeclBase.Use.Default;
  2099.                     decl.DefaultValueRaw = decl.DefaultValueExpanded = xa.DefaultValue;
  2100.                 }
  2101.                 else {
  2102.                     if (xa.Use == XmlSchemaUse.Required) {
  2103.                         decl.Presence = SchemaDeclBase.Use.RequiredFixed;
  2104.                     }
  2105.                     else {
  2106.                         decl.Presence = SchemaDeclBase.Use.Fixed;
  2107.                     }
  2108.                     decl.DefaultValueRaw = decl.DefaultValueExpanded = xa.FixedValue;
  2109.                 }
  2110.                 if (decl.Datatype != null) {
  2111.                     if (decl.Datatype.TypeCode == XmlTypeCode.Id) {
  2112.                         SendValidationEvent(Res.Sch_DefaultIdValue, xa);
  2113.                     }
  2114.                     else {
  2115.                         decl.DefaultValueTyped = decl.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xa), true);
  2116.                     }
  2117.                 }
  2118.             }
  2119.             else {
  2120.                 switch (xa.Use) {
  2121.                     case XmlSchemaUse.None:
  2122.                     case XmlSchemaUse.Optional:
  2123.                         decl.Presence = SchemaDeclBase.Use.Implied;
  2124.                         break;
  2125.                     case XmlSchemaUse.Required:
  2126.                         decl.Presence = SchemaDeclBase.Use.Required;
  2127.                         break;
  2128.                     case XmlSchemaUse.Prohibited:
  2129.                         break;
  2130.                 }
  2131.             }
  2132.         }
  2133.        
  2134.         private void CompileIdentityConstraint(XmlSchemaIdentityConstraint xi)
  2135.         {
  2136.             if (xi.IsProcessing) {
  2137.                 xi.CompiledConstraint = CompiledIdentityConstraint.Empty;
  2138.                 SendValidationEvent(Res.Sch_IdentityConstraintCircularRef, xi);
  2139.                 return;
  2140.             }
  2141.            
  2142.             if (xi.CompiledConstraint != null) {
  2143.                 return;
  2144.             }
  2145.            
  2146.             xi.IsProcessing = true;
  2147.             CompiledIdentityConstraint compic = null;
  2148.             try {
  2149.                 SchemaNamespaceManager xnmgr = new SchemaNamespaceManager(xi);
  2150.                 compic = new CompiledIdentityConstraint(xi, xnmgr);
  2151.                 if (xi is XmlSchemaKeyref) {
  2152.                     XmlSchemaIdentityConstraint ic = (XmlSchemaIdentityConstraint)this.identityConstraints[((XmlSchemaKeyref)xi).Refer];
  2153.                     if (ic == null) {
  2154.                         throw new XmlSchemaException(Res.Sch_UndeclaredIdentityConstraint, ((XmlSchemaKeyref)xi).Refer.ToString(), xi);
  2155.                     }
  2156.                     CompileIdentityConstraint(ic);
  2157.                     if (ic.CompiledConstraint == null) {
  2158.                         throw new XmlSchemaException(Res.Sch_RefInvalidIdentityConstraint, ((XmlSchemaKeyref)xi).Refer.ToString(), xi);
  2159.                     }
  2160.                     // keyref has the different cardinality with the key it referred
  2161.                     if (ic.Fields.Count != xi.Fields.Count) {
  2162.                         throw new XmlSchemaException(Res.Sch_RefInvalidCardin, xi.QualifiedName.ToString(), xi);
  2163.                     }
  2164.                     // keyref can only refer to key/unique
  2165.                     if (ic.CompiledConstraint.Role == CompiledIdentityConstraint.ConstraintRole.Keyref) {
  2166.                         throw new XmlSchemaException(Res.Sch_ReftoKeyref, xi.QualifiedName.ToString(), xi);
  2167.                     }
  2168.                 }
  2169.                 xi.CompiledConstraint = compic;
  2170.             }
  2171.             catch (XmlSchemaException e) {
  2172.                 if (e.SourceSchemaObject == null) {
  2173.                     e.SetSource(xi);
  2174.                 }
  2175.                 SendValidationEvent(e);
  2176.                 xi.CompiledConstraint = CompiledIdentityConstraint.Empty;
  2177.                 // empty is better than null here, stop quickly when circle referencing
  2178.             }
  2179.             finally {
  2180.                 xi.IsProcessing = false;
  2181.             }
  2182.            
  2183.         }
  2184.        
  2185.         private void CompileElement(XmlSchemaElement xe)
  2186.         {
  2187.             if (xe.IsProcessing) {
  2188.                 SendValidationEvent(Res.Sch_ElementCircularRef, xe);
  2189.                 return;
  2190.             }
  2191.             if (xe.ElementDecl != null) {
  2192.                 return;
  2193.             }
  2194.             xe.IsProcessing = true;
  2195.             SchemaElementDecl decl = null;
  2196.             try {
  2197.                 if (!xe.RefName.IsEmpty) {
  2198.                     XmlSchemaElement e = (XmlSchemaElement)elements[xe.RefName];
  2199.                     if (e == null) {
  2200.                         throw new XmlSchemaException(Res.Sch_UndeclaredElement, xe.RefName.ToString(), xe);
  2201.                     }
  2202.                     CompileElement(e);
  2203.                     if (e.ElementDecl == null) {
  2204.                         throw new XmlSchemaException(Res.Sch_RefInvalidElement, xe.RefName.ToString(), xe);
  2205.                     }
  2206.                     xe.SetElementType(e.ElementSchemaType);
  2207.                     decl = e.ElementDecl.Clone();
  2208.                 }
  2209.                 else {
  2210.                     if (xe.SchemaType != null) {
  2211.                         xe.SetElementType(xe.SchemaType);
  2212.                     }
  2213.                     else if (!xe.SchemaTypeName.IsEmpty) {
  2214.                         xe.SetElementType(GetAnySchemaType(xe.SchemaTypeName));
  2215.                         if (xe.ElementSchemaType == null) {
  2216.                             throw new XmlSchemaException(Res.Sch_UndeclaredType, xe.SchemaTypeName.ToString(), xe);
  2217.                         }
  2218.                     }
  2219.                     else if (!xe.SubstitutionGroup.IsEmpty) {
  2220.                         XmlSchemaElement examplar = (XmlSchemaElement)elements[xe.SubstitutionGroup];
  2221.                         if (examplar == null) {
  2222.                             throw new XmlSchemaException(Res.Sch_UndeclaredEquivClass, xe.SubstitutionGroup.Name.ToString(CultureInfo.InvariantCulture), xe);
  2223.                         }
  2224.                         if (examplar.IsProcessing) {
  2225.                             //Circular subst group; already detected by now
  2226.                             return;
  2227.                         }
  2228.                         CompileElement(examplar);
  2229.                         if (examplar.ElementDecl == null) {
  2230.                             //If head is invalid, fall back to AnyType
  2231.                             xe.SetElementType(XmlSchemaComplexType.AnyType);
  2232.                             decl = XmlSchemaComplexType.AnyType.ElementDecl.Clone();
  2233.                         }
  2234.                         else {
  2235.                             xe.SetElementType(examplar.ElementSchemaType);
  2236.                             decl = examplar.ElementDecl.Clone();
  2237.                         }
  2238.                     }
  2239.                     else {
  2240.                         xe.SetElementType(XmlSchemaComplexType.AnyType);
  2241.                         decl = XmlSchemaComplexType.AnyType.ElementDecl.Clone();
  2242.                     }
  2243.                    
  2244.                     if (decl == null) {
  2245.                         Debug.Assert(xe.ElementSchemaType != null);
  2246.                         if (xe.ElementSchemaType is XmlSchemaComplexType) {
  2247.                             XmlSchemaComplexType complexType = (XmlSchemaComplexType)xe.ElementSchemaType;
  2248.                             CompileComplexType(complexType);
  2249.                             if (complexType.ElementDecl != null) {
  2250.                                 decl = complexType.ElementDecl.Clone();
  2251.                                 // decl.LocalElements = complexType.LocalElementDecls;
  2252.                             }
  2253.                         }
  2254.                         else if (xe.ElementSchemaType is XmlSchemaSimpleType) {
  2255.                             XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)xe.ElementSchemaType;
  2256.                             CompileSimpleType(simpleType);
  2257.                             if (simpleType.ElementDecl != null) {
  2258.                                 decl = simpleType.ElementDecl.Clone();
  2259.                             }
  2260.                         }
  2261.                     }
  2262.                     Debug.Assert(decl != null);
  2263.                     decl.Name = xe.QualifiedName;
  2264.                     decl.IsAbstract = xe.IsAbstract;
  2265.                     XmlSchemaComplexType ct = xe.ElementSchemaType as XmlSchemaComplexType;
  2266.                     if (ct != null) {
  2267.                         decl.IsAbstract |= ct.IsAbstract;
  2268.                     }
  2269.                     decl.IsNillable = xe.IsNillable;
  2270.                     decl.Block |= xe.BlockResolved;
  2271.                 }
  2272.                 if (decl.Datatype != null) {
  2273.                     decl.Datatype.VerifySchemaValid(notations, xe);
  2274.                 }
  2275.                
  2276.                 if (xe.DefaultValue != null || xe.FixedValue != null) {
  2277.                     if (decl.ContentValidator != null) {
  2278.                         if (decl.ContentValidator.ContentType == XmlSchemaContentType.TextOnly || (decl.ContentValidator.ContentType == XmlSchemaContentType.Mixed && decl.ContentValidator.IsEmptiable)) {
  2279.                             if (xe.DefaultValue != null) {
  2280.                                 decl.Presence = SchemaDeclBase.Use.Default;
  2281.                                 decl.DefaultValueRaw = xe.DefaultValue;
  2282.                             }
  2283.                             else {
  2284.                                 decl.Presence = SchemaDeclBase.Use.Fixed;
  2285.                                 decl.DefaultValueRaw = xe.FixedValue;
  2286.                             }
  2287.                             if (decl.Datatype != null) {
  2288.                                 if (decl.Datatype.TypeCode == XmlTypeCode.Id) {
  2289.                                     SendValidationEvent(Res.Sch_DefaultIdValue, xe);
  2290.                                 }
  2291.                                 else {
  2292.                                     decl.DefaultValueTyped = decl.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xe), true);
  2293.                                 }
  2294.                             }
  2295.                             else {
  2296.                                 //Mixed with emptiable particle
  2297.                                 decl.DefaultValueTyped = DatatypeImplementation.AnySimpleType.Datatype.ParseValue(decl.DefaultValueRaw, NameTable, new SchemaNamespaceManager(xe));
  2298.                             }
  2299.                         }
  2300.                         else {
  2301.                             throw new XmlSchemaException(Res.Sch_ElementCannotHaveValue, xe);
  2302.                         }
  2303.                     }
  2304.                 }
  2305.                 if (xe.HasConstraints) {
  2306.                     XmlSchemaObjectCollection constraints = xe.Constraints;
  2307.                     CompiledIdentityConstraint[] compiledConstraints = new CompiledIdentityConstraint[constraints.Count];
  2308.                     int idx = 0;
  2309.                     foreach (XmlSchemaIdentityConstraint constraint in constraints) {
  2310.                         CompileIdentityConstraint(constraint);
  2311.                         compiledConstraints[idx++] = constraint.CompiledConstraint;
  2312.                     }
  2313.                     decl.Constraints = compiledConstraints;
  2314.                 }
  2315.                 decl.SchemaElement = xe;
  2316.                 //So this is available for PSVI
  2317.                 xe.ElementDecl = decl;
  2318.             }
  2319.             catch (XmlSchemaException e) {
  2320.                 if (e.SourceSchemaObject == null) {
  2321.                     e.SetSource(xe);
  2322.                 }
  2323.                 SendValidationEvent(e);
  2324.                 xe.ElementDecl = SchemaElementDecl.Empty;
  2325.             }
  2326.             finally {
  2327.                 xe.IsProcessing = false;
  2328.             }
  2329.         }
  2330.        
  2331.         private ContentValidator CompileComplexContent(XmlSchemaComplexType complexType)
  2332.         {
  2333.             if (complexType.ContentType == XmlSchemaContentType.Empty) {
  2334.                 return ContentValidator.Empty;
  2335.             }
  2336.             else if (complexType.ContentType == XmlSchemaContentType.TextOnly) {
  2337.                 return ContentValidator.TextOnly;
  2338.             }
  2339.             XmlSchemaParticle particle = complexType.ContentTypeParticle;
  2340.             if (particle == null || particle == XmlSchemaParticle.Empty) {
  2341.                 if (complexType.ContentType == XmlSchemaContentType.ElementOnly) {
  2342.                     return ContentValidator.Empty;
  2343.                 }
  2344.                 else {
  2345.                     return ContentValidator.Mixed;
  2346.                 }
  2347.             }
  2348.             PushComplexType(complexType);
  2349.             if (particle is XmlSchemaAll) {
  2350.                 XmlSchemaAll all = (XmlSchemaAll)particle;
  2351.                 AllElementsContentValidator contentValidator = new AllElementsContentValidator(complexType.ContentType, all.Items.Count, all.MinOccurs == decimal.Zero);
  2352.                 foreach (XmlSchemaElement localElement in all.Items) {
  2353.                     if (!contentValidator.AddElement(localElement.QualifiedName, localElement, localElement.MinOccurs == decimal.Zero)) {
  2354.                         SendValidationEvent(Res.Sch_DupElement, localElement.QualifiedName.ToString(), localElement);
  2355.                     }
  2356.                 }
  2357.                 return contentValidator;
  2358.             }
  2359.             else {
  2360.                 ParticleContentValidator contentValidator = new ParticleContentValidator(complexType.ContentType, CompilationSettings.EnableUpaCheck);
  2361.                 #if DEBUG
  2362.                 string name = complexType.Name != null ? complexType.Name : string.Empty;
  2363.                 Debug.WriteLineIf(DiagnosticsSwitches.XmlSchema.TraceVerbose, "CompileComplexContent: " + name + DumpContentModel(particle));
  2364.                 #endif
  2365.                 try {
  2366.                     contentValidator.Start();
  2367.                     complexType.HasWildCard = BuildParticleContentModel(contentValidator, particle);
  2368.                     return contentValidator.Finish(true);
  2369.                 }
  2370.                 catch (UpaException e) {
  2371.                     if (e.Particle1 is XmlSchemaElement) {
  2372.                         if (e.Particle2 is XmlSchemaElement) {
  2373.                             SendValidationEvent(Res.Sch_NonDeterministic, ((XmlSchemaElement)e.Particle1).QualifiedName.ToString(), (XmlSchemaElement)e.Particle2);
  2374.                         }
  2375.                         else {
  2376.                             SendValidationEvent(Res.Sch_NonDeterministicAnyEx, ((XmlSchemaAny)e.Particle2).ResolvedNamespace, ((XmlSchemaElement)e.Particle1).QualifiedName.ToString(), (XmlSchemaAny)e.Particle2);
  2377.                         }
  2378.                     }
  2379.                     else {
  2380.                         if (e.Particle2 is XmlSchemaElement) {
  2381.                             SendValidationEvent(Res.Sch_NonDeterministicAnyEx, ((XmlSchemaAny)e.Particle1).ResolvedNamespace, ((XmlSchemaElement)e.Particle2).QualifiedName.ToString(), (XmlSchemaElement)e.Particle2);
  2382.                         }
  2383.                         else {
  2384.                             SendValidationEvent(Res.Sch_NonDeterministicAnyAny, ((XmlSchemaAny)e.Particle1).ResolvedNamespace, ((XmlSchemaAny)e.Particle2).ResolvedNamespace, (XmlSchemaAny)e.Particle2);
  2385.                         }
  2386.                     }
  2387.                     return XmlSchemaComplexType.AnyTypeContentValidator;
  2388.                 }
  2389.                 catch (NotSupportedException) {
  2390.                     SendValidationEvent(Res.Sch_ComplexContentModel, complexType, XmlSeverityType.Warning);
  2391.                     return XmlSchemaComplexType.AnyTypeContentValidator;
  2392.                 }
  2393.             }
  2394.         }
  2395.        
  2396.         #if DEBUG
  2397.         private string DumpContentModel(XmlSchemaParticle particle)
  2398.         {
  2399.             StringBuilder sb = new StringBuilder();
  2400.             DumpContentModelTo(sb, particle);
  2401.             return sb.ToString();
  2402.         }
  2403.        
  2404.         private void DumpContentModelTo(StringBuilder sb, XmlSchemaParticle particle)
  2405.         {
  2406.             if (particle is XmlSchemaElement) {
  2407.                 sb.Append(((XmlSchemaElement)particle).QualifiedName);
  2408.             }
  2409.             else if (particle is XmlSchemaAny) {
  2410.                 sb.Append("<");
  2411.                 sb.Append(((XmlSchemaAny)particle).NamespaceList.ToString());
  2412.                 sb.Append(">");
  2413.             }
  2414.             else if (particle is XmlSchemaAll) {
  2415.                 XmlSchemaAll all = (XmlSchemaAll)particle;
  2416.                 sb.Append("[");
  2417.                 bool first = true;
  2418.                 foreach (XmlSchemaElement localElement in all.Items) {
  2419.                     if (first) {
  2420.                         first = false;
  2421.                     }
  2422.                     else {
  2423.                         sb.Append(", ");
  2424.                     }
  2425.                     sb.Append(localElement.QualifiedName.Name);
  2426.                     if (localElement.MinOccurs == decimal.Zero) {
  2427.                         sb.Append("?");
  2428.                     }
  2429.                 }
  2430.                 sb.Append("]");
  2431.             }
  2432.             else if (particle is XmlSchemaGroupBase) {
  2433.                 XmlSchemaGroupBase gb = (XmlSchemaGroupBase)particle;
  2434.                 sb.Append("(");
  2435.                 string delimeter = (particle is XmlSchemaChoice) ? " | " : ", ";
  2436.                 bool first = true;
  2437.                 foreach (XmlSchemaParticle p in gb.Items) {
  2438.                     if (first) {
  2439.                         first = false;
  2440.                     }
  2441.                     else {
  2442.                         sb.Append(delimeter);
  2443.                     }
  2444.                     DumpContentModelTo(sb, p);
  2445.                 }
  2446.                 sb.Append(")");
  2447.             }
  2448.             else {
  2449.                 Debug.Assert(particle == XmlSchemaParticle.Empty);
  2450.                 sb.Append("<>");
  2451.             }
  2452.             if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.One) {
  2453.                 // nothing
  2454.             }
  2455.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.One) {
  2456.                 sb.Append("?");
  2457.             }
  2458.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.MaxValue) {
  2459.                 sb.Append("*");
  2460.             }
  2461.             else if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.MaxValue) {
  2462.                 sb.Append("+");
  2463.             }
  2464.             else {
  2465.                 sb.Append("{" + particle.MinOccurs.ToString(NumberFormatInfo.InvariantInfo) + ", " + particle.MaxOccurs.ToString(NumberFormatInfo.InvariantInfo) + "}");
  2466.             }
  2467.         }
  2468.         #endif
  2469.        
  2470.         private bool BuildParticleContentModel(ParticleContentValidator contentValidator, XmlSchemaParticle particle)
  2471.         {
  2472.             bool hasWildCard = false;
  2473.             if (particle is XmlSchemaElement) {
  2474.                 XmlSchemaElement element = (XmlSchemaElement)particle;
  2475.                 contentValidator.AddName(element.QualifiedName, element);
  2476.             }
  2477.             else if (particle is XmlSchemaAny) {
  2478.                 hasWildCard = true;
  2479.                 XmlSchemaAny any = (XmlSchemaAny)particle;
  2480.                 contentValidator.AddNamespaceList(any.NamespaceList, any);
  2481.             }
  2482.             else if (particle is XmlSchemaGroupBase) {
  2483.                 XmlSchemaObjectCollection particles = ((XmlSchemaGroupBase)particle).Items;
  2484.                 bool isChoice = particle is XmlSchemaChoice;
  2485.                 contentValidator.OpenGroup();
  2486.                 bool first = true;
  2487.                 foreach (XmlSchemaParticle p in particles) {
  2488.                     Debug.Assert(!p.IsEmpty);
  2489.                     if (first) {
  2490.                         first = false;
  2491.                     }
  2492.                     else if (isChoice) {
  2493.                         contentValidator.AddChoice();
  2494.                     }
  2495.                     else {
  2496.                         contentValidator.AddSequence();
  2497.                     }
  2498.                     hasWildCard = BuildParticleContentModel(contentValidator, p);
  2499.                 }
  2500.                 contentValidator.CloseGroup();
  2501.             }
  2502.             else {
  2503.                 Debug.Assert(false);
  2504.             }
  2505.             if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.One) {
  2506.                 // nothing
  2507.             }
  2508.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.One) {
  2509.                 contentValidator.AddQMark();
  2510.             }
  2511.             else if (particle.MinOccurs == decimal.Zero && particle.MaxOccurs == decimal.MaxValue) {
  2512.                 contentValidator.AddStar();
  2513.             }
  2514.             else if (particle.MinOccurs == decimal.One && particle.MaxOccurs == decimal.MaxValue) {
  2515.                 contentValidator.AddPlus();
  2516.             }
  2517.             else {
  2518.                 contentValidator.AddLeafRange(particle.MinOccurs, particle.MaxOccurs);
  2519.             }
  2520.             return hasWildCard;
  2521.         }
  2522.        
  2523.         private void CompileParticleElements(XmlSchemaComplexType complexType, XmlSchemaParticle particle)
  2524.         {
  2525.             if (particle is XmlSchemaElement) {
  2526.                 XmlSchemaElement localElement = (XmlSchemaElement)particle;
  2527.                 CompileElement(localElement);
  2528.                 if (complexType.LocalElements[localElement.QualifiedName] == null) {
  2529.                     complexType.LocalElements.Add(localElement.QualifiedName, localElement);
  2530.                 }
  2531.                 else {
  2532.                     complexType.HasDuplicateDecls = true;
  2533.                     XmlSchemaElement element = (XmlSchemaElement)complexType.LocalElements[localElement.QualifiedName];
  2534.                     if (element.ElementSchemaType != localElement.ElementSchemaType) {
  2535.                         SendValidationEvent(Res.Sch_ElementTypeCollision, particle);
  2536.                     }
  2537.                 }
  2538.             }
  2539.             else if (particle is XmlSchemaGroupBase) {
  2540.                 XmlSchemaObjectCollection particles = ((XmlSchemaGroupBase)particle).Items;
  2541.                 foreach (XmlSchemaParticle p in particles) {
  2542.                     CompileParticleElements(complexType, p);
  2543.                 }
  2544.             }
  2545.         }
  2546.        
  2547.         private void CompileParticleElements(XmlSchemaParticle particle)
  2548.         {
  2549.             //For checking redefined group particle derivation
  2550.             if (particle is XmlSchemaElement) {
  2551.                 XmlSchemaElement localElement = (XmlSchemaElement)particle;
  2552.                 CompileElement(localElement);
  2553.             }
  2554.             else if (particle is XmlSchemaGroupBase) {
  2555.                 XmlSchemaObjectCollection particles = ((XmlSchemaGroupBase)particle).Items;
  2556.                 foreach (XmlSchemaParticle p in particles) {
  2557.                     CompileParticleElements(p);
  2558.                 }
  2559.             }
  2560.         }
  2561.        
  2562.         private void CompileComplexTypeElements(XmlSchemaComplexType complexType)
  2563.         {
  2564.             if (complexType.IsProcessing) {
  2565.                 SendValidationEvent(Res.Sch_TypeCircularRef, complexType);
  2566.                 return;
  2567.             }
  2568.             complexType.IsProcessing = true;
  2569.             try {
  2570.                 if (complexType.ContentTypeParticle != XmlSchemaParticle.Empty) {
  2571.                     CompileParticleElements(complexType, complexType.ContentTypeParticle);
  2572.                 }
  2573.             }
  2574.             finally {
  2575.                 complexType.IsProcessing = false;
  2576.             }
  2577.         }
  2578.        
  2579.         private XmlSchemaSimpleType GetSimpleType(XmlQualifiedName name)
  2580.         {
  2581.             XmlSchemaSimpleType type = schemaTypes[name] as XmlSchemaSimpleType;
  2582.             if (type != null) {
  2583.                 CompileSimpleType(type);
  2584.             }
  2585.             else {
  2586.                 type = DatatypeImplementation.GetSimpleTypeFromXsdType(name);
  2587.             }
  2588.             return type;
  2589.         }
  2590.        
  2591.         private XmlSchemaComplexType GetComplexType(XmlQualifiedName name)
  2592.         {
  2593.             XmlSchemaComplexType type = schemaTypes[name] as XmlSchemaComplexType;
  2594.             if (type != null) {
  2595.                 CompileComplexType(type);
  2596.             }
  2597.             return type;
  2598.         }
  2599.        
  2600.         private XmlSchemaType GetAnySchemaType(XmlQualifiedName name)
  2601.         {
  2602.             XmlSchemaType type = (XmlSchemaType)schemaTypes[name];
  2603.             if (type != null) {
  2604.                 if (type is XmlSchemaComplexType) {
  2605.                     CompileComplexType((XmlSchemaComplexType)type);
  2606.                 }
  2607.                 else {
  2608.                     CompileSimpleType((XmlSchemaSimpleType)type);
  2609.                 }
  2610.                 return type;
  2611.             }
  2612.             else {
  2613.                 //Its is a built-in simpleType
  2614.                 XmlSchemaSimpleType simpleType = DatatypeImplementation.GetSimpleTypeFromXsdType(name);
  2615.                 return simpleType;
  2616.             }
  2617.         }
  2618.        
  2619.         private void CopyPosition(XmlSchemaObject to, XmlSchemaObject from, bool copyParent)
  2620.         {
  2621.             to.SourceUri = from.SourceUri;
  2622.             to.LinePosition = from.LinePosition;
  2623.             to.LineNumber = from.LineNumber;
  2624.             if (copyParent) {
  2625.                 to.Parent = from.Parent;
  2626.             }
  2627.         }
  2628.        
  2629.         private bool IsFixedEqual(SchemaDeclBase baseDecl, SchemaDeclBase derivedDecl)
  2630.         {
  2631.            
  2632.             if (baseDecl.Presence == SchemaDeclBase.Use.Fixed || baseDecl.Presence == SchemaDeclBase.Use.RequiredFixed) {
  2633.                 object baseFixedValue = baseDecl.DefaultValueTyped;
  2634.                 object derivedFixedValue = derivedDecl.DefaultValueTyped;
  2635.                
  2636.                 Debug.Assert(baseFixedValue != null);
  2637.                 if (derivedDecl.Presence != SchemaDeclBase.Use.Fixed && derivedDecl.Presence != SchemaDeclBase.Use.RequiredFixed) {
  2638.                     return false;
  2639.                 }
  2640.                 Debug.Assert(derivedFixedValue != null);
  2641.                 XmlSchemaDatatype baseDatatype = baseDecl.Datatype;
  2642.                 XmlSchemaDatatype derivedDatatype = derivedDecl.Datatype;
  2643.                
  2644.                 if (baseDatatype.Variety == XmlSchemaDatatypeVariety.Union) {
  2645.                     if (derivedDatatype.Variety == XmlSchemaDatatypeVariety.Union) {
  2646.                         if (!derivedDatatype.IsEqual(baseFixedValue, derivedFixedValue)) {
  2647.                             return false;
  2648.                         }
  2649.                     }
  2650.                     else {
  2651.                         //Base is union and derived is member of union
  2652.                         XsdSimpleValue simpleFixedValue = baseDecl.DefaultValueTyped as XsdSimpleValue;
  2653.                         Debug.Assert(simpleFixedValue != null);
  2654.                         XmlSchemaDatatype memberType = simpleFixedValue.XmlType.Datatype;
  2655.                         if (!memberType.IsComparable(derivedDatatype) || !derivedDatatype.IsEqual(simpleFixedValue.TypedValue, derivedFixedValue)) {
  2656.                             //base type {Union of long & string}, derived type {int}
  2657.                             return false;
  2658.                         }
  2659.                     }
  2660.                 }
  2661.                 else if (!derivedDatatype.IsEqual(baseFixedValue, derivedFixedValue)) {
  2662.                     return false;
  2663.                 }
  2664.             }
  2665.             return true;
  2666.         }
  2667.     }
  2668.    
  2669. }
  2670. // namespace System.Xml

Developer Fusion