Merge pull request #3389 from lambdageek/bug-43099
[mono.git] / mcs / class / referencesource / System.Runtime.Serialization / System / Runtime / Serialization / SchemaImporter.cs
1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4
5 namespace System.Runtime.Serialization
6 {
7     using System;
8     using System.Collections;
9     using System.Collections.Generic;
10     using System.Collections.ObjectModel;
11     using System.Diagnostics;
12     using System.Globalization;
13     using System.IO;
14     using System.Security;
15     using System.Runtime.Diagnostics;
16     using System.Xml;
17     using System.Xml.Schema;
18     using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
19     using SchemaObjectDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, SchemaObjectInfo>;
20     using System.Runtime.Serialization.Diagnostics;
21
22     class SchemaImporter
23     {
24         DataContractSet dataContractSet;
25         XmlSchemaSet schemaSet;
26         ICollection<XmlQualifiedName> typeNames;
27         ICollection<XmlSchemaElement> elements;
28         XmlQualifiedName[] elementTypeNames;
29         bool importXmlDataType;
30         SchemaObjectDictionary schemaObjects;
31         List<XmlSchemaRedefine> redefineList;
32         bool needToImportKnownTypesForObject;
33
34         [Fx.Tag.SecurityNote(Critical = "Static field used to store serialization schema elements from future versions."
35             + " Static fields are marked SecurityCritical or readonly to prevent data from being modified or leaked to other components in appdomain.")]
36         [SecurityCritical]
37         static Hashtable serializationSchemaElements;
38
39         internal SchemaImporter(XmlSchemaSet schemas, ICollection<XmlQualifiedName> typeNames, ICollection<XmlSchemaElement> elements, XmlQualifiedName[] elementTypeNames, DataContractSet dataContractSet, bool importXmlDataType)
40         {
41             this.dataContractSet = dataContractSet;
42             this.schemaSet = schemas;
43             this.typeNames = typeNames;
44             this.elements = elements;
45             this.elementTypeNames = elementTypeNames;
46             this.importXmlDataType = importXmlDataType;
47         }
48
49         internal void Import()
50         {
51             if (!schemaSet.Contains(Globals.SerializationNamespace))
52             {
53                 StringReader reader = new StringReader(Globals.SerializationSchema);
54                 XmlSchema schema = XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
55                 if (schema == null)
56                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CouldNotReadSerializationSchema, Globals.SerializationNamespace)));
57                 schemaSet.Add(schema);
58             }
59
60             try
61             {
62                 CompileSchemaSet(schemaSet);
63             }
64 #pragma warning suppress 56500 // covered by FxCOP
65             catch (Exception ex)
66             {
67                 if (Fx.IsFatal(ex))
68                 {
69                     throw;
70                 }
71                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportInvalidSchemas), ex));
72             }
73
74             if (typeNames == null)
75             {
76                 ICollection schemaList = schemaSet.Schemas();
77                 foreach (object schemaObj in schemaList)
78                 {
79                     if (schemaObj == null)
80                         throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportNullSchema)));
81
82                     XmlSchema schema = (XmlSchema)schemaObj;
83                     if (schema.TargetNamespace != Globals.SerializationNamespace
84                         && schema.TargetNamespace != Globals.SchemaNamespace)
85                     {
86                         foreach (XmlSchemaObject typeObj in schema.SchemaTypes.Values)
87                         {
88                             ImportType((XmlSchemaType)typeObj);
89                         }
90                         foreach (XmlSchemaElement element in schema.Elements.Values)
91                         {
92                             if (element.SchemaType != null)
93                                 ImportAnonymousGlobalElement(element, element.QualifiedName, schema.TargetNamespace);
94                         }
95                     }
96                 }
97             }
98             else
99             {
100                 foreach (XmlQualifiedName typeName in typeNames)
101                 {
102                     if (typeName == null)
103                         throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.CannotImportNullDataContractName)));
104                     ImportType(typeName);
105                 }
106
107                 if (elements != null)
108                 {
109                     int i = 0;
110                     foreach (XmlSchemaElement element in elements)
111                     {
112                         XmlQualifiedName typeName = element.SchemaTypeName;
113                         if (typeName != null && typeName.Name.Length > 0)
114                         {
115                             elementTypeNames[i++] = ImportType(typeName).StableName;
116                         }
117                         else
118                         {
119                             XmlSchema schema = SchemaHelper.GetSchemaWithGlobalElementDeclaration(element, schemaSet);
120                             if (schema == null)
121                             {
122                                 elementTypeNames[i++] = ImportAnonymousElement(element, element.QualifiedName).StableName;
123                             }
124                             else
125                             {
126                                 elementTypeNames[i++] = ImportAnonymousGlobalElement(element, element.QualifiedName, schema.TargetNamespace).StableName;
127                             }
128                         }
129                     }
130                 }
131             }
132             ImportKnownTypesForObject();
133         }
134
135         internal static void CompileSchemaSet(XmlSchemaSet schemaSet)
136         {
137             if (schemaSet.Contains(XmlSchema.Namespace))
138                 schemaSet.Compile();
139             else
140             {
141                 // Add base XSD schema with top level element named "schema"
142                 XmlSchema xsdSchema = new XmlSchema();
143                 xsdSchema.TargetNamespace = XmlSchema.Namespace;
144                 XmlSchemaElement element = new XmlSchemaElement();
145                 element.Name = Globals.SchemaLocalName;
146                 element.SchemaType = new XmlSchemaComplexType();
147                 xsdSchema.Items.Add(element);
148                 schemaSet.Add(xsdSchema);
149                 schemaSet.Compile();
150             }
151         }
152
153         SchemaObjectDictionary SchemaObjects
154         {
155             get
156             {
157                 if (schemaObjects == null)
158                     schemaObjects = CreateSchemaObjects();
159                 return schemaObjects;
160             }
161         }
162
163         List<XmlSchemaRedefine> RedefineList
164         {
165             get
166             {
167                 if (redefineList == null)
168                     redefineList = CreateRedefineList();
169                 return redefineList;
170             }
171         }
172
173         void ImportKnownTypes(XmlQualifiedName typeName)
174         {
175             SchemaObjectInfo schemaObjectInfo;
176             if (SchemaObjects.TryGetValue(typeName, out schemaObjectInfo))
177             {
178                 List<XmlSchemaType> knownTypes = schemaObjectInfo.knownTypes;
179                 if (knownTypes != null)
180                 {
181                     foreach (XmlSchemaType knownType in knownTypes)
182                         ImportType(knownType);
183                 }
184             }
185         }
186
187         internal static bool IsObjectContract(DataContract dataContract)
188         {
189             Dictionary<Type, object> previousCollectionTypes = new Dictionary<Type, object>();
190             while (dataContract is CollectionDataContract)
191             {
192                 if (dataContract.OriginalUnderlyingType == null)
193                 {
194                     dataContract = ((CollectionDataContract)dataContract).ItemContract;
195                     continue;
196                 }
197
198                 if (!previousCollectionTypes.ContainsKey(dataContract.OriginalUnderlyingType))
199                 {
200                     previousCollectionTypes.Add(dataContract.OriginalUnderlyingType, dataContract.OriginalUnderlyingType);
201                     dataContract = ((CollectionDataContract)dataContract).ItemContract;
202                 }
203                 else
204                 {
205                     break;
206                 }
207             }
208
209             return dataContract is PrimitiveDataContract && ((PrimitiveDataContract)dataContract).UnderlyingType == Globals.TypeOfObject;
210         }
211
212         void ImportKnownTypesForObject()
213         {
214             if (!needToImportKnownTypesForObject)
215                 return;
216             needToImportKnownTypesForObject = false;
217             if (dataContractSet.KnownTypesForObject == null)
218             {
219                 SchemaObjectInfo schemaObjectInfo;
220                 if (SchemaObjects.TryGetValue(SchemaExporter.AnytypeQualifiedName, out schemaObjectInfo))
221                 {
222                     List<XmlSchemaType> knownTypes = schemaObjectInfo.knownTypes;
223                     if (knownTypes != null)
224                     {
225                         DataContractDictionary knownDataContracts = new DataContractDictionary();
226                         foreach (XmlSchemaType knownType in knownTypes)
227                         {
228                             // Expected: will throw exception if schema set contains types that are not supported 
229                             DataContract dataContract = ImportType(knownType);
230                             DataContract existingContract;
231                             if (!knownDataContracts.TryGetValue(dataContract.StableName, out existingContract))
232                             {
233                                 knownDataContracts.Add(dataContract.StableName, dataContract);
234                             }
235                         }
236                         dataContractSet.KnownTypesForObject = knownDataContracts;
237                     }
238                 }
239             }
240         }
241
242         internal SchemaObjectDictionary CreateSchemaObjects()
243         {
244             SchemaObjectDictionary schemaObjects = new SchemaObjectDictionary();
245             ICollection schemaList = schemaSet.Schemas();
246             List<XmlSchemaType> knownTypesForObject = new List<XmlSchemaType>();
247             schemaObjects.Add(SchemaExporter.AnytypeQualifiedName, new SchemaObjectInfo(null, null, null, knownTypesForObject));
248
249             foreach (XmlSchema schema in schemaList)
250             {
251                 if (schema.TargetNamespace != Globals.SerializationNamespace)
252                 {
253                     foreach (XmlSchemaObject schemaObj in schema.SchemaTypes.Values)
254                     {
255                         XmlSchemaType schemaType = schemaObj as XmlSchemaType;
256                         if (schemaType != null)
257                         {
258                             knownTypesForObject.Add(schemaType);
259
260                             XmlQualifiedName currentTypeName = new XmlQualifiedName(schemaType.Name, schema.TargetNamespace);
261                             SchemaObjectInfo schemaObjectInfo;
262                             if (schemaObjects.TryGetValue(currentTypeName, out schemaObjectInfo))
263                             {
264                                 schemaObjectInfo.type = schemaType;
265                                 schemaObjectInfo.schema = schema;
266                             }
267                             else
268                             {
269                                 schemaObjects.Add(currentTypeName, new SchemaObjectInfo(schemaType, null, schema, null));
270                             }
271
272                             XmlQualifiedName baseTypeName = GetBaseTypeName(schemaType);
273                             if (baseTypeName != null)
274                             {
275                                 SchemaObjectInfo baseTypeInfo;
276                                 if (schemaObjects.TryGetValue(baseTypeName, out baseTypeInfo))
277                                 {
278                                     if (baseTypeInfo.knownTypes == null)
279                                     {
280                                         baseTypeInfo.knownTypes = new List<XmlSchemaType>();
281                                     }
282                                 }
283                                 else
284                                 {
285                                     baseTypeInfo = new SchemaObjectInfo(null, null, null, new List<XmlSchemaType>());
286                                     schemaObjects.Add(baseTypeName, baseTypeInfo);
287                                 }
288                                 baseTypeInfo.knownTypes.Add(schemaType);
289                             }
290                         }
291                     }
292                     foreach (XmlSchemaObject schemaObj in schema.Elements.Values)
293                     {
294                         XmlSchemaElement schemaElement = schemaObj as XmlSchemaElement;
295                         if (schemaElement != null)
296                         {
297                             XmlQualifiedName currentElementName = new XmlQualifiedName(schemaElement.Name, schema.TargetNamespace);
298                             SchemaObjectInfo schemaObjectInfo;
299                             if (schemaObjects.TryGetValue(currentElementName, out schemaObjectInfo))
300                             {
301                                 schemaObjectInfo.element = schemaElement;
302                                 schemaObjectInfo.schema = schema;
303                             }
304                             else
305                             {
306                                 schemaObjects.Add(currentElementName, new SchemaObjectInfo(null, schemaElement, schema, null));
307                             }
308                         }
309                     }
310                 }
311             }
312             return schemaObjects;
313         }
314
315         XmlQualifiedName GetBaseTypeName(XmlSchemaType type)
316         {
317             XmlQualifiedName baseTypeName = null;
318             XmlSchemaComplexType complexType = type as XmlSchemaComplexType;
319             if (complexType != null)
320             {
321                 if (complexType.ContentModel != null)
322                 {
323                     XmlSchemaComplexContent complexContent = complexType.ContentModel as XmlSchemaComplexContent;
324                     if (complexContent != null)
325                     {
326                         XmlSchemaComplexContentExtension extension = complexContent.Content as XmlSchemaComplexContentExtension;
327                         if (extension != null)
328                             baseTypeName = extension.BaseTypeName;
329                     }
330                 }
331             }
332             return baseTypeName;
333         }
334
335         List<XmlSchemaRedefine> CreateRedefineList()
336         {
337             List<XmlSchemaRedefine> list = new List<XmlSchemaRedefine>();
338
339             ICollection schemaList = schemaSet.Schemas();
340             foreach (object schemaObj in schemaList)
341             {
342                 XmlSchema schema = schemaObj as XmlSchema;
343                 if (schema == null)
344                     continue;
345                 foreach (XmlSchemaExternal ext in schema.Includes)
346                 {
347                     XmlSchemaRedefine redefine = ext as XmlSchemaRedefine;
348                     if (redefine != null)
349                         list.Add(redefine);
350                 }
351             }
352
353             return list;
354         }
355
356         [Fx.Tag.SecurityNote(Critical = "Sets critical properties on XmlDataContract.",
357             Safe = "Called during schema import/code generation.")]
358         [SecuritySafeCritical]
359         DataContract ImportAnonymousGlobalElement(XmlSchemaElement element, XmlQualifiedName typeQName, string ns)
360         {
361             DataContract contract = ImportAnonymousElement(element, typeQName);
362             XmlDataContract xmlDataContract = contract as XmlDataContract;
363             if (xmlDataContract != null)
364             {
365                 xmlDataContract.SetTopLevelElementName(new XmlQualifiedName(element.Name, ns));
366                 xmlDataContract.IsTopLevelElementNullable = element.IsNillable;
367             }
368             return contract;
369         }
370
371         DataContract ImportAnonymousElement(XmlSchemaElement element, XmlQualifiedName typeQName)
372         {
373             if (SchemaHelper.GetSchemaType(SchemaObjects, typeQName) != null)
374             {
375                 for (int i = 1;; i++)
376                 {
377                     typeQName = new XmlQualifiedName(typeQName.Name + i.ToString(NumberFormatInfo.InvariantInfo), typeQName.Namespace);
378                     if (SchemaHelper.GetSchemaType(SchemaObjects, typeQName) == null)
379                         break;
380                     if (i == Int32.MaxValue)
381                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CannotComputeUniqueName, element.Name)));
382                 }
383             }
384             if (element.SchemaType == null)
385                 return ImportType(SchemaExporter.AnytypeQualifiedName);
386             else
387                 return ImportType(element.SchemaType, typeQName, true/*isAnonymous*/);
388         }
389
390         DataContract ImportType(XmlQualifiedName typeName)
391         {
392             DataContract dataContract = DataContract.GetBuiltInDataContract(typeName.Name, typeName.Namespace);
393             if (dataContract == null)
394             {
395                 XmlSchemaType type = SchemaHelper.GetSchemaType(SchemaObjects, typeName);
396                 if (type == null)
397                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.SpecifiedTypeNotFoundInSchema, typeName.Name, typeName.Namespace)));
398                 dataContract = ImportType(type);
399             }
400             if (IsObjectContract(dataContract))
401                 needToImportKnownTypesForObject = true;
402             return dataContract;
403         }
404
405         DataContract ImportType(XmlSchemaType type)
406         {
407             return ImportType(type, type.QualifiedName, false/*isAnonymous*/);
408         }
409
410
411         DataContract ImportType(XmlSchemaType type, XmlQualifiedName typeName, bool isAnonymous)
412         {
413             DataContract dataContract = dataContractSet[typeName];
414             if (dataContract != null)
415                 return dataContract;
416
417             InvalidDataContractException invalidContractException;
418             try
419             {
420                 foreach (XmlSchemaRedefine redefine in RedefineList)
421                 {
422                     if (redefine.SchemaTypes[typeName] != null)
423                         ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RedefineNotSupported));
424                 }
425
426                 if (type is XmlSchemaSimpleType)
427                 {
428                     XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)type;
429                     XmlSchemaSimpleTypeContent content = simpleType.Content;
430                     if (content is XmlSchemaSimpleTypeUnion)
431                         ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleTypeUnionNotSupported));
432                     else if (content is XmlSchemaSimpleTypeList)
433                         dataContract = ImportFlagsEnum(typeName, (XmlSchemaSimpleTypeList)content, simpleType.Annotation);
434                     else if (content is XmlSchemaSimpleTypeRestriction)
435                     {
436                         XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content;
437                         if (CheckIfEnum(restriction))
438                         {
439                             dataContract = ImportEnum(typeName, restriction, false /*isFlags*/, simpleType.Annotation);
440                         }
441                         else
442                         {
443                             dataContract = ImportSimpleTypeRestriction(typeName, restriction);
444                             if (dataContract.IsBuiltInDataContract && !isAnonymous)
445                             {
446                                 dataContractSet.InternalAdd(typeName, dataContract);
447                             }
448                         }
449                     }
450                 }
451                 else if (type is XmlSchemaComplexType)
452                 {
453                     XmlSchemaComplexType complexType = (XmlSchemaComplexType)type;
454                     if (complexType.ContentModel == null)
455                     {
456                         CheckComplexType(typeName, complexType);
457                         dataContract = ImportType(typeName, complexType.Particle, complexType.Attributes, complexType.AnyAttribute, null /* baseTypeName */, complexType.Annotation);
458                     }
459                     else
460                     {
461                         XmlSchemaContentModel contentModel = complexType.ContentModel;
462                         if (contentModel is XmlSchemaSimpleContent)
463                             ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleContentNotSupported));
464                         else if (contentModel is XmlSchemaComplexContent)
465                         {
466                             XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)contentModel;
467                             if (complexContent.IsMixed)
468                                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MixedContentNotSupported));
469
470                             if (complexContent.Content is XmlSchemaComplexContentExtension)
471                             {
472                                 XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)complexContent.Content;
473                                 dataContract = ImportType(typeName, extension.Particle, extension.Attributes, extension.AnyAttribute, extension.BaseTypeName, complexType.Annotation);
474                             }
475                             else if (complexContent.Content is XmlSchemaComplexContentRestriction)
476                             {
477                                 XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)complexContent.Content;
478                                 XmlQualifiedName baseTypeName = restriction.BaseTypeName;
479                                 if (baseTypeName == SchemaExporter.AnytypeQualifiedName)
480                                     dataContract = ImportType(typeName, restriction.Particle, restriction.Attributes, restriction.AnyAttribute, null /* baseTypeName */, complexType.Annotation);
481                                 else
482                                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ComplexTypeRestrictionNotSupported));
483                             }
484                         }
485                     }
486                 }
487
488                 if (dataContract == null)
489                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, String.Empty);
490                 if (type.QualifiedName != XmlQualifiedName.Empty)
491                     ImportTopLevelElement(typeName);
492                 ImportDataContractExtension(type, dataContract);
493                 ImportGenericInfo(type, dataContract);
494                 ImportKnownTypes(typeName);
495
496                 return dataContract;
497             }
498             catch (InvalidDataContractException e)
499             {
500                 invalidContractException = e;
501             }
502
503             // Execution gets to this point if InvalidDataContractException was thrown
504             if (importXmlDataType)
505             {
506                 RemoveFailedContract(typeName);
507                 return ImportXmlDataType(typeName, type, isAnonymous);
508             }
509             Type referencedType;
510             if (dataContractSet.TryGetReferencedType(typeName, dataContract, out referencedType)
511                 || (string.IsNullOrEmpty(type.Name) && dataContractSet.TryGetReferencedType(ImportActualType(type.Annotation, typeName, typeName), dataContract, out referencedType)))
512             {
513                 if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(referencedType))
514                 {
515                     RemoveFailedContract(typeName);
516                     return ImportXmlDataType(typeName, type, isAnonymous);
517                 }
518             }
519             XmlDataContract specialContract = ImportSpecialXmlDataType(type, isAnonymous);
520             if (specialContract != null)
521             {
522                 this.dataContractSet.Remove(typeName);
523                 return specialContract;
524             }
525
526             throw invalidContractException;
527         }
528
529         private void RemoveFailedContract(XmlQualifiedName typeName)
530         {
531             ClassDataContract oldContract = this.dataContractSet[typeName] as ClassDataContract;
532             this.dataContractSet.Remove(typeName);
533             if (oldContract != null)
534             {
535                 ClassDataContract ancestorDataContract = oldContract.BaseContract;
536                 while (ancestorDataContract != null)
537                 {
538                     ancestorDataContract.KnownDataContracts.Remove(typeName);
539                     ancestorDataContract = ancestorDataContract.BaseContract;
540                 }
541                 if (dataContractSet.KnownTypesForObject != null)
542                     dataContractSet.KnownTypesForObject.Remove(typeName);
543             }
544         }
545
546         bool CheckIfEnum(XmlSchemaSimpleTypeRestriction restriction)
547         {
548             foreach (XmlSchemaFacet facet in restriction.Facets)
549             {
550                 if (!(facet is XmlSchemaEnumerationFacet))
551                     return false;
552             }
553
554             XmlQualifiedName expectedBase = SchemaExporter.StringQualifiedName;
555             if (restriction.BaseTypeName != XmlQualifiedName.Empty)
556             {
557                 return ((restriction.BaseTypeName == expectedBase && restriction.Facets.Count > 0) || ImportType(restriction.BaseTypeName) is EnumDataContract);
558             }
559             else if (restriction.BaseType != null)
560             {
561                 DataContract baseContract = ImportType(restriction.BaseType);
562                 return (baseContract.StableName == expectedBase || baseContract is EnumDataContract);
563             }
564
565             return false;
566         }
567
568         bool CheckIfCollection(XmlSchemaSequence rootSequence)
569         {
570             if (rootSequence.Items == null || rootSequence.Items.Count == 0)
571                 return false;
572             RemoveOptionalUnknownSerializationElements(rootSequence.Items);
573             if (rootSequence.Items.Count != 1)
574                 return false;
575
576             XmlSchemaObject o = rootSequence.Items[0];
577             if (!(o is XmlSchemaElement))
578                 return false;
579
580             XmlSchemaElement localElement = (XmlSchemaElement)o;
581             return (localElement.MaxOccursString == Globals.OccursUnbounded || localElement.MaxOccurs > 1);
582         }
583
584         bool CheckIfISerializable(XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes)
585         {
586             if (rootSequence.Items == null || rootSequence.Items.Count == 0)
587                 return false;
588
589             RemoveOptionalUnknownSerializationElements(rootSequence.Items);
590
591             if (attributes == null || attributes.Count == 0)
592                 return false;
593
594             return (rootSequence.Items.Count == 1 && rootSequence.Items[0] is XmlSchemaAny);
595         }
596
597         [Fx.Tag.SecurityNote(Critical = "Initializes critical static fields.",
598             Safe = "Doesn't leak anything.")]
599         [SecuritySafeCritical]
600         void RemoveOptionalUnknownSerializationElements(XmlSchemaObjectCollection items)
601         {
602             for (int i = 0; i < items.Count; i++)
603             {
604                 XmlSchemaElement element = items[i] as XmlSchemaElement;
605                 if (element != null && element.RefName != null &&
606                    element.RefName.Namespace == Globals.SerializationNamespace &&
607                    element.MinOccurs == 0)
608                 {
609                     if (serializationSchemaElements == null)
610                     {
611                         XmlSchema serializationSchema = XmlSchema.Read(XmlReader.Create(new StringReader(Globals.SerializationSchema)), null);
612                         serializationSchemaElements = new Hashtable();
613                         foreach (XmlSchemaObject schemaObject in serializationSchema.Items)
614                         {
615                             XmlSchemaElement schemaElement = schemaObject as XmlSchemaElement;
616                             if (schemaElement != null)
617                                 serializationSchemaElements.Add(schemaElement.Name, schemaElement);
618                         }
619                     }
620                     if (!serializationSchemaElements.ContainsKey(element.RefName.Name))
621                     {
622                         items.RemoveAt(i);
623                         i--;
624                     }
625                 }
626             }
627         }
628
629         DataContract ImportType(XmlQualifiedName typeName, XmlSchemaParticle rootParticle, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, XmlQualifiedName baseTypeName, XmlSchemaAnnotation annotation)
630         {
631             DataContract dataContract = null;
632             bool isDerived = (baseTypeName != null);
633
634             bool isReference;
635             ImportAttributes(typeName, attributes, anyAttribute, out isReference);
636
637             if (rootParticle == null)
638                 dataContract = ImportClass(typeName, new XmlSchemaSequence(), baseTypeName, annotation, isReference);
639             else if (!(rootParticle is XmlSchemaSequence))
640                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootParticleMustBeSequence));
641             else
642             {
643                 XmlSchemaSequence rootSequence = (XmlSchemaSequence)rootParticle;
644                 if (rootSequence.MinOccurs != 1)
645                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootSequenceMustBeRequired));
646                 if (rootSequence.MaxOccurs != 1)
647                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.RootSequenceMaxOccursMustBe));
648
649                 if (!isDerived && CheckIfCollection(rootSequence))
650                     dataContract = ImportCollection(typeName, rootSequence, attributes, annotation, isReference);
651                 else if (CheckIfISerializable(rootSequence, attributes))
652                     dataContract = ImportISerializable(typeName, rootSequence, baseTypeName, attributes, annotation);
653                 else
654                     dataContract = ImportClass(typeName, rootSequence, baseTypeName, annotation, isReference);
655             }
656             return dataContract;
657         }
658
659         [Fx.Tag.SecurityNote(Critical = "Sets critical properties on ClassDataContract.",
660             Safe = "Called during schema import/code generation.")]
661         [SecuritySafeCritical]
662         ClassDataContract ImportClass(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlQualifiedName baseTypeName, XmlSchemaAnnotation annotation, bool isReference)
663         {
664             ClassDataContract dataContract = new ClassDataContract();
665             dataContract.StableName = typeName;
666             AddDataContract(dataContract);
667
668             dataContract.IsValueType = IsValueType(typeName, annotation);
669             dataContract.IsReference = isReference;
670             if (baseTypeName != null)
671             {
672                 ImportBaseContract(baseTypeName, dataContract);
673                 if (dataContract.BaseContract.IsISerializable)
674                 {
675                     if (IsISerializableDerived(typeName, rootSequence))
676                         dataContract.IsISerializable = true;
677                     else
678                         ThrowTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(SR.DerivedTypeNotISerializable, baseTypeName.Name, baseTypeName.Namespace));
679                 }
680                 if (dataContract.BaseContract.IsReference)
681                 {
682                     dataContract.IsReference = true;
683                 }
684             }
685
686             if (!dataContract.IsISerializable)
687             {
688                 dataContract.Members = new List<DataMember>();
689                 RemoveOptionalUnknownSerializationElements(rootSequence.Items);
690                 for (int memberIndex = 0; memberIndex < rootSequence.Items.Count; memberIndex++)
691                 {
692                     XmlSchemaElement element = rootSequence.Items[memberIndex] as XmlSchemaElement;
693                     if (element == null)
694                         ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MustContainOnlyLocalElements));
695                     ImportClassMember(element, dataContract);
696                 }
697             }
698
699             return dataContract;
700         }
701
702         [Fx.Tag.SecurityNote(Critical = "Sets critical properties on XmlDataContract.",
703             Safe = "Called during schema import/code generation.")]
704         [SecuritySafeCritical]
705         DataContract ImportXmlDataType(XmlQualifiedName typeName, XmlSchemaType xsdType, bool isAnonymous)
706         {
707             DataContract dataContract = dataContractSet[typeName];
708             if (dataContract != null)
709                 return dataContract;
710
711             XmlDataContract xmlDataContract = ImportSpecialXmlDataType(xsdType, isAnonymous);
712             if (xmlDataContract != null)
713                 return xmlDataContract;
714
715             xmlDataContract = new XmlDataContract();
716             xmlDataContract.StableName = typeName;
717             xmlDataContract.IsValueType = false;
718             AddDataContract(xmlDataContract);
719             if (xsdType != null)
720             {
721                 ImportDataContractExtension(xsdType, xmlDataContract);
722                 xmlDataContract.IsValueType = IsValueType(typeName, xsdType.Annotation);
723                 xmlDataContract.IsTypeDefinedOnImport = true;
724                 xmlDataContract.XsdType = isAnonymous ? xsdType : null;
725                 xmlDataContract.HasRoot = !IsXmlAnyElementType(xsdType as XmlSchemaComplexType);
726             }
727             else
728             {
729                 //Value type can be used by both nillable and non-nillable elements but reference type cannot be used by non nillable elements
730                 xmlDataContract.IsValueType = true;
731                 xmlDataContract.IsTypeDefinedOnImport = false;
732                 xmlDataContract.HasRoot = true;
733                 if (DiagnosticUtility.ShouldTraceVerbose)
734                 {
735                     TraceUtility.Trace(TraceEventType.Verbose, TraceCode.XsdImportAnnotationFailed,
736                         SR.GetString(SR.TraceCodeXsdImportAnnotationFailed), new StringTraceRecord("Type", typeName.Namespace + ":" + typeName.Name));
737                 }
738             }
739             if (!isAnonymous)
740             {
741                 bool isNullable;
742                 xmlDataContract.SetTopLevelElementName(SchemaHelper.GetGlobalElementDeclaration(schemaSet, typeName, out isNullable));
743                 xmlDataContract.IsTopLevelElementNullable = isNullable;
744             }
745             return xmlDataContract;
746         }
747
748         private XmlDataContract ImportSpecialXmlDataType(XmlSchemaType xsdType, bool isAnonymous)
749         {
750             if (!isAnonymous)
751                 return null;
752             XmlSchemaComplexType complexType = xsdType as XmlSchemaComplexType;
753             if (complexType == null)
754                 return null;
755             if (IsXmlAnyElementType(complexType))
756             {
757                 //check if the type is XElement
758                 XmlQualifiedName xlinqTypeName = new XmlQualifiedName("XElement", "http://schemas.datacontract.org/2004/07/System.Xml.Linq");
759                 Type referencedType;
760                 if (dataContractSet.TryGetReferencedType(xlinqTypeName, null, out referencedType)
761                     && Globals.TypeOfIXmlSerializable.IsAssignableFrom(referencedType))
762                 {
763                     XmlDataContract xmlDataContract = new XmlDataContract(referencedType);
764                     AddDataContract(xmlDataContract);
765                     return xmlDataContract;
766                 }
767                 //otherwise, assume XmlElement
768                 return (XmlDataContract)DataContract.GetBuiltInDataContract(Globals.TypeOfXmlElement);
769             }
770             if (IsXmlAnyType(complexType))
771                 return (XmlDataContract)DataContract.GetBuiltInDataContract(Globals.TypeOfXmlNodeArray);
772             return null;
773         }
774
775         bool IsXmlAnyElementType(XmlSchemaComplexType xsdType)
776         {
777             if (xsdType == null)
778                 return false;
779
780             XmlSchemaSequence sequence = xsdType.Particle as XmlSchemaSequence;
781             if (sequence == null)
782                 return false;
783
784             if (sequence.Items == null || sequence.Items.Count != 1)
785                 return false;
786
787             XmlSchemaAny any = sequence.Items[0] as XmlSchemaAny;
788             if (any == null || any.Namespace != null)
789                 return false;
790
791             if (xsdType.AnyAttribute != null || (xsdType.Attributes != null && xsdType.Attributes.Count > 0))
792                 return false;
793
794             return true;
795         }
796
797         bool IsXmlAnyType(XmlSchemaComplexType xsdType)
798         {
799             if (xsdType == null)
800                 return false;
801
802             XmlSchemaSequence sequence = xsdType.Particle as XmlSchemaSequence;
803             if (sequence == null)
804                 return false;
805
806             if (sequence.Items == null || sequence.Items.Count != 1)
807                 return false;
808
809             XmlSchemaAny any = sequence.Items[0] as XmlSchemaAny;
810             if (any == null || any.Namespace != null)
811                 return false;
812
813             if (any.MaxOccurs != Decimal.MaxValue)
814                 return false;
815
816             if (xsdType.AnyAttribute == null || xsdType.Attributes.Count > 0)
817                 return false;
818
819             return true;
820         }
821
822         bool IsValueType(XmlQualifiedName typeName, XmlSchemaAnnotation annotation)
823         {
824             string isValueTypeInnerText = GetInnerText(typeName, ImportAnnotation(annotation, SchemaExporter.IsValueTypeName));
825             if (isValueTypeInnerText != null)
826             {
827                 try
828                 {
829                     return XmlConvert.ToBoolean(isValueTypeInnerText);
830                 }
831                 catch (FormatException fe)
832                 {
833                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.IsValueTypeFormattedIncorrectly, isValueTypeInnerText, fe.Message));
834                 }
835             }
836             return false;
837         }
838
839         [Fx.Tag.SecurityNote(Critical = "Sets critical properties on ClassDataContract.",
840             Safe = "Called during schema import/code generation.")]
841         [SecuritySafeCritical]
842         ClassDataContract ImportISerializable(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlQualifiedName baseTypeName, XmlSchemaObjectCollection attributes, XmlSchemaAnnotation annotation)
843         {
844             ClassDataContract dataContract = new ClassDataContract();
845             dataContract.StableName = typeName;
846             dataContract.IsISerializable = true;
847             AddDataContract(dataContract);
848
849             dataContract.IsValueType = IsValueType(typeName, annotation);
850             if (baseTypeName == null)
851                 CheckISerializableBase(typeName, rootSequence, attributes);
852             else
853             {
854                 ImportBaseContract(baseTypeName, dataContract);
855                 if (!dataContract.BaseContract.IsISerializable)
856                     ThrowISerializableTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(SR.BaseTypeNotISerializable, baseTypeName.Name, baseTypeName.Namespace));
857                 if (!IsISerializableDerived(typeName, rootSequence))
858                     ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDerivedContainsOneOrMoreItems));
859             }
860
861             return dataContract;
862         }
863
864         void CheckISerializableBase(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes)
865         {
866             if (rootSequence == null)
867                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
868
869             if (rootSequence.Items == null || rootSequence.Items.Count < 1)
870                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
871             else if (rootSequence.Items.Count > 1)
872                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableContainsMoreThanOneItems));
873
874             XmlSchemaObject o = rootSequence.Items[0];
875             if (!(o is XmlSchemaAny))
876                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableDoesNotContainAny));
877
878             XmlSchemaAny wildcard = (XmlSchemaAny)o;
879             XmlSchemaAny iSerializableWildcardElement = SchemaExporter.ISerializableWildcardElement;
880             if (wildcard.MinOccurs != iSerializableWildcardElement.MinOccurs)
881                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardMinOccursMustBe, iSerializableWildcardElement.MinOccurs));
882             if (wildcard.MaxOccursString != iSerializableWildcardElement.MaxOccursString)
883                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardMaxOccursMustBe, iSerializableWildcardElement.MaxOccursString));
884             if (wildcard.Namespace != iSerializableWildcardElement.Namespace)
885                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardNamespaceInvalid, iSerializableWildcardElement.Namespace));
886             if (wildcard.ProcessContents != iSerializableWildcardElement.ProcessContents)
887                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableWildcardProcessContentsInvalid, iSerializableWildcardElement.ProcessContents));
888
889             XmlQualifiedName factoryTypeAttributeRefName = SchemaExporter.ISerializableFactoryTypeAttribute.RefName;
890             bool containsFactoryTypeAttribute = false;
891             if (attributes != null)
892             {
893                 for (int i = 0; i < attributes.Count; i++)
894                 {
895                     o = attributes[i];
896                     if (o is XmlSchemaAttribute)
897                     {
898                         if (((XmlSchemaAttribute)o).RefName == factoryTypeAttributeRefName)
899                         {
900                             containsFactoryTypeAttribute = true;
901                             break;
902                         }
903                     }
904                 }
905             }
906             if (!containsFactoryTypeAttribute)
907                 ThrowISerializableTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ISerializableMustRefFactoryTypeAttribute, factoryTypeAttributeRefName.Name, factoryTypeAttributeRefName.Namespace));
908         }
909
910         bool IsISerializableDerived(XmlQualifiedName typeName, XmlSchemaSequence rootSequence)
911         {
912             return (rootSequence == null || rootSequence.Items == null || rootSequence.Items.Count == 0);
913         }
914
915         [Fx.Tag.SecurityNote(Critical = "Sets critical BaseContract property on ClassDataContract.",
916             Safe = "Called during schema import/code generation.")]
917         [SecuritySafeCritical]
918         void ImportBaseContract(XmlQualifiedName baseTypeName, ClassDataContract dataContract)
919         {
920             ClassDataContract baseContract = ImportType(baseTypeName) as ClassDataContract;
921             if (baseContract == null)
922                 ThrowTypeCannotBeImportedException(dataContract.StableName.Name, dataContract.StableName.Namespace, SR.GetString(dataContract.IsISerializable ? SR.InvalidISerializableDerivation : SR.InvalidClassDerivation, baseTypeName.Name, baseTypeName.Namespace));
923
924             // Note: code ignores IsValueType annotation if derived type exists
925             if (baseContract.IsValueType)
926                 baseContract.IsValueType = false;
927
928             ClassDataContract ancestorDataContract = baseContract;
929             while (ancestorDataContract != null)
930             {
931                 DataContractDictionary knownDataContracts = ancestorDataContract.KnownDataContracts;
932                 if (knownDataContracts == null)
933                 {
934                     knownDataContracts = new DataContractDictionary();
935                     ancestorDataContract.KnownDataContracts = knownDataContracts;
936                 }
937                 knownDataContracts.Add(dataContract.StableName, dataContract);
938                 ancestorDataContract = ancestorDataContract.BaseContract;
939             }
940
941             dataContract.BaseContract = baseContract;
942         }
943
944         void ImportTopLevelElement(XmlQualifiedName typeName)
945         {
946             XmlSchemaElement topLevelElement = SchemaHelper.GetSchemaElement(SchemaObjects, typeName);
947             // Top level element of same name is not required, but is validated if it is present 
948             if (topLevelElement == null)
949                 return;
950             else
951             {
952                 XmlQualifiedName elementTypeName = topLevelElement.SchemaTypeName;
953                 if (elementTypeName.IsEmpty)
954                 {
955                     if (topLevelElement.SchemaType != null)
956                         ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AnonymousTypeNotSupported, typeName.Name, typeName.Namespace));
957                     else
958                         elementTypeName = SchemaExporter.AnytypeQualifiedName;
959                 }
960                 if (elementTypeName != typeName)
961                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.TopLevelElementRepresentsDifferentType, topLevelElement.SchemaTypeName.Name, topLevelElement.SchemaTypeName.Namespace));
962                 CheckIfElementUsesUnsupportedConstructs(typeName, topLevelElement);
963             }
964         }
965
966         void ImportClassMember(XmlSchemaElement element, ClassDataContract dataContract)
967         {
968             XmlQualifiedName typeName = dataContract.StableName;
969
970             if (element.MinOccurs > 1)
971                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementMinOccursMustBe, element.Name));
972             if (element.MaxOccurs != 1)
973                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementMaxOccursMustBe, element.Name));
974
975             DataContract memberTypeContract = null;
976             string memberName = element.Name;
977             bool memberIsRequired = (element.MinOccurs > 0);
978             bool memberIsNullable = element.IsNillable;
979             bool memberEmitDefaultValue;
980             int memberOrder = 0;
981
982             XmlSchemaForm elementForm = (element.Form == XmlSchemaForm.None) ? SchemaHelper.GetSchemaWithType(SchemaObjects, schemaSet, typeName).ElementFormDefault : element.Form;
983             if (elementForm != XmlSchemaForm.Qualified)
984                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.FormMustBeQualified, element.Name));
985             CheckIfElementUsesUnsupportedConstructs(typeName, element);
986
987             if (element.SchemaTypeName.IsEmpty)
988             {
989                 if (element.SchemaType != null)
990                     memberTypeContract = ImportAnonymousElement(element, new XmlQualifiedName(String.Format(CultureInfo.InvariantCulture, "{0}.{1}Type", typeName.Name, element.Name), typeName.Namespace));
991                 else if (!element.RefName.IsEmpty)
992                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementRefOnLocalElementNotSupported, element.RefName.Name, element.RefName.Namespace));
993                 else
994                     memberTypeContract = ImportType(SchemaExporter.AnytypeQualifiedName);
995             }
996             else
997             {
998                 XmlQualifiedName memberTypeName = ImportActualType(element.Annotation, element.SchemaTypeName, typeName);
999                 memberTypeContract = ImportType(memberTypeName);
1000                 if (IsObjectContract(memberTypeContract))
1001                     needToImportKnownTypesForObject = true;
1002             }
1003             bool? emitDefaultValueFromAnnotation = ImportEmitDefaultValue(element.Annotation, typeName);
1004             if (!memberTypeContract.IsValueType && !memberIsNullable)
1005             {
1006                 if (emitDefaultValueFromAnnotation != null && emitDefaultValueFromAnnotation.Value)
1007                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidEmitDefaultAnnotation, memberName, typeName.Name, typeName.Namespace)));
1008                 memberEmitDefaultValue = false;
1009             }
1010             else
1011                 memberEmitDefaultValue = emitDefaultValueFromAnnotation != null ? emitDefaultValueFromAnnotation.Value : Globals.DefaultEmitDefaultValue;
1012
1013             int prevMemberIndex = dataContract.Members.Count - 1;
1014             if (prevMemberIndex >= 0)
1015             {
1016                 DataMember prevMember = dataContract.Members[prevMemberIndex];
1017                 if (prevMember.Order > Globals.DefaultOrder)
1018                     memberOrder = dataContract.Members.Count;
1019                 DataMember currentMember = new DataMember(memberTypeContract, memberName, memberIsNullable, memberIsRequired, memberEmitDefaultValue, memberOrder);
1020                 int compare = ClassDataContract.DataMemberComparer.Singleton.Compare(prevMember, currentMember);
1021                 if (compare == 0)
1022                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.CannotHaveDuplicateElementNames, memberName));
1023                 else if (compare > 0)
1024                     memberOrder = dataContract.Members.Count;
1025             }
1026             DataMember dataMember = new DataMember(memberTypeContract, memberName, memberIsNullable, memberIsRequired, memberEmitDefaultValue, memberOrder);
1027
1028             XmlQualifiedName surrogateDataAnnotationName = SchemaExporter.SurrogateDataAnnotationName;
1029             dataContractSet.SetSurrogateData(dataMember, ImportSurrogateData(ImportAnnotation(element.Annotation, surrogateDataAnnotationName), surrogateDataAnnotationName.Name, surrogateDataAnnotationName.Namespace));
1030
1031             dataContract.Members.Add(dataMember);
1032         }
1033
1034         private bool? ImportEmitDefaultValue(XmlSchemaAnnotation annotation, XmlQualifiedName typeName)
1035         {
1036             XmlElement defaultValueElement = ImportAnnotation(annotation, SchemaExporter.DefaultValueAnnotation);
1037             if (defaultValueElement == null)
1038                 return null;
1039             XmlNode emitDefaultValueAttribute = defaultValueElement.Attributes.GetNamedItem(Globals.EmitDefaultValueAttribute);
1040             string emitDefaultValueString = (emitDefaultValueAttribute == null) ? null : emitDefaultValueAttribute.Value;
1041             if (emitDefaultValueString == null)
1042                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.DefaultValueAnnotation.Name, typeName.Name, typeName.Namespace, Globals.EmitDefaultValueAttribute)));
1043             return XmlConvert.ToBoolean(emitDefaultValueString);
1044         }
1045
1046         internal static XmlQualifiedName ImportActualType(XmlSchemaAnnotation annotation, XmlQualifiedName defaultTypeName, XmlQualifiedName typeName)
1047         {
1048             XmlElement actualTypeElement = ImportAnnotation(annotation, SchemaExporter.ActualTypeAnnotationName);
1049             if (actualTypeElement == null)
1050                 return defaultTypeName;
1051
1052             XmlNode nameAttribute = actualTypeElement.Attributes.GetNamedItem(Globals.ActualTypeNameAttribute);
1053             string name = (nameAttribute == null) ? null : nameAttribute.Value;
1054             if (name == null)
1055                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.ActualTypeAnnotationName.Name, typeName.Name, typeName.Namespace, Globals.ActualTypeNameAttribute)));
1056             XmlNode nsAttribute = actualTypeElement.Attributes.GetNamedItem(Globals.ActualTypeNamespaceAttribute);
1057             string ns = (nsAttribute == null) ? null : nsAttribute.Value;
1058             if (ns == null)
1059                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.AnnotationAttributeNotFound, SchemaExporter.ActualTypeAnnotationName.Name, typeName.Name, typeName.Namespace, Globals.ActualTypeNamespaceAttribute)));
1060             return new XmlQualifiedName(name, ns);
1061         }
1062
1063         [Fx.Tag.SecurityNote(Critical = "Sets critical properties on CollectionDataContract.",
1064             Safe = "Called during schema import/code generation.")]
1065         [SecuritySafeCritical]
1066         CollectionDataContract ImportCollection(XmlQualifiedName typeName, XmlSchemaSequence rootSequence, XmlSchemaObjectCollection attributes, XmlSchemaAnnotation annotation, bool isReference)
1067         {
1068             CollectionDataContract dataContract = new CollectionDataContract(CollectionKind.Array);
1069             dataContract.StableName = typeName;
1070             AddDataContract(dataContract);
1071
1072             dataContract.IsReference = isReference;
1073
1074             // CheckIfCollection has already checked if sequence contains exactly one item with maxOccurs="unbounded" or maxOccurs > 1 
1075             XmlSchemaElement element = (XmlSchemaElement)rootSequence.Items[0];
1076
1077             dataContract.IsItemTypeNullable = element.IsNillable;
1078             dataContract.ItemName = element.Name;
1079
1080             XmlSchemaForm elementForm = (element.Form == XmlSchemaForm.None) ? SchemaHelper.GetSchemaWithType(SchemaObjects, schemaSet, typeName).ElementFormDefault : element.Form;
1081             if (elementForm != XmlSchemaForm.Qualified)
1082                 ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ArrayItemFormMustBe, element.Name));
1083             CheckIfElementUsesUnsupportedConstructs(typeName, element);
1084
1085             if (element.SchemaTypeName.IsEmpty)
1086             {
1087                 if (element.SchemaType != null)
1088                 {
1089                     XmlQualifiedName shortName = new XmlQualifiedName(element.Name, typeName.Namespace);
1090                     DataContract contract = dataContractSet[shortName];
1091                     if (contract == null)
1092                     {
1093                         dataContract.ItemContract = ImportAnonymousElement(element, shortName);
1094                     }
1095                     else
1096                     {
1097                         XmlQualifiedName fullName = new XmlQualifiedName(String.Format(CultureInfo.InvariantCulture, "{0}.{1}Type", typeName.Name, element.Name), typeName.Namespace);
1098                         dataContract.ItemContract = ImportAnonymousElement(element, fullName);
1099                     }
1100                 }
1101                 else if (!element.RefName.IsEmpty)
1102                     ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.ElementRefOnLocalElementNotSupported, element.RefName.Name, element.RefName.Namespace));
1103                 else
1104                     dataContract.ItemContract = ImportType(SchemaExporter.AnytypeQualifiedName);
1105             }
1106             else
1107             {
1108                 dataContract.ItemContract = ImportType(element.SchemaTypeName);
1109             }
1110
1111             if (IsDictionary(typeName, annotation))
1112             {
1113                 ClassDataContract keyValueContract = dataContract.ItemContract as ClassDataContract;
1114                 DataMember key = null, value = null;
1115                 if (keyValueContract == null || keyValueContract.Members == null || keyValueContract.Members.Count != 2
1116                     || !(key = keyValueContract.Members[0]).IsRequired || !(value = keyValueContract.Members[1]).IsRequired)
1117                 {
1118                     ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidKeyValueType, element.Name));
1119                 }
1120                 if (keyValueContract.Namespace != dataContract.Namespace)
1121                 {
1122                     ThrowArrayTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidKeyValueTypeNamespace, element.Name, keyValueContract.Namespace));
1123                 }
1124                 keyValueContract.IsValueType = true;
1125                 dataContract.KeyName = key.Name;
1126                 dataContract.ValueName = value.Name;
1127                 if (element.SchemaType != null)
1128                 {
1129                     dataContractSet.Remove(keyValueContract.StableName);
1130
1131                     GenericInfo genericInfo = new GenericInfo(DataContract.GetStableName(Globals.TypeOfKeyValue), Globals.TypeOfKeyValue.FullName);
1132                     genericInfo.Add(GetGenericInfoForDataMember(key));
1133                     genericInfo.Add(GetGenericInfoForDataMember(value));
1134                     genericInfo.AddToLevel(0, 2);
1135                     dataContract.ItemContract.StableName = new XmlQualifiedName(genericInfo.GetExpandedStableName().Name, typeName.Namespace);
1136                 }
1137             }
1138
1139             return dataContract;
1140         }
1141
1142         GenericInfo GetGenericInfoForDataMember(DataMember dataMember)
1143         {
1144             GenericInfo genericInfo = null;
1145             if (dataMember.MemberTypeContract.IsValueType && dataMember.IsNullable)
1146             {
1147                 genericInfo = new GenericInfo(DataContract.GetStableName(Globals.TypeOfNullable), Globals.TypeOfNullable.FullName);
1148                 genericInfo.Add(new GenericInfo(dataMember.MemberTypeContract.StableName, null));
1149             }
1150             else
1151             {
1152                 genericInfo = new GenericInfo(dataMember.MemberTypeContract.StableName, null);
1153             }
1154
1155             return genericInfo;
1156         }
1157
1158         bool IsDictionary(XmlQualifiedName typeName, XmlSchemaAnnotation annotation)
1159         {
1160             string isDictionaryInnerText = GetInnerText(typeName, ImportAnnotation(annotation, SchemaExporter.IsDictionaryAnnotationName));
1161             if (isDictionaryInnerText != null)
1162             {
1163                 try
1164                 {
1165                     return XmlConvert.ToBoolean(isDictionaryInnerText);
1166                 }
1167                 catch (FormatException fe)
1168                 {
1169                     ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.IsDictionaryFormattedIncorrectly, isDictionaryInnerText, fe.Message));
1170                 }
1171             }
1172             return false;
1173         }
1174
1175         EnumDataContract ImportFlagsEnum(XmlQualifiedName typeName, XmlSchemaSimpleTypeList list, XmlSchemaAnnotation annotation)
1176         {
1177             XmlSchemaSimpleType anonymousType = list.ItemType;
1178             if (anonymousType == null)
1179                 ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumListMustContainAnonymousType));
1180
1181             XmlSchemaSimpleTypeContent content = anonymousType.Content;
1182             if (content is XmlSchemaSimpleTypeUnion)
1183                 ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumUnionInAnonymousTypeNotSupported));
1184             else if (content is XmlSchemaSimpleTypeList)
1185                 ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumListInAnonymousTypeNotSupported));
1186             else if (content is XmlSchemaSimpleTypeRestriction)
1187             {
1188                 XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content;
1189                 if (CheckIfEnum(restriction))
1190                     return ImportEnum(typeName, restriction, true /*isFlags*/, annotation);
1191                 else
1192                     ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumRestrictionInvalid));
1193             }
1194             return null;
1195         }
1196
1197         [Fx.Tag.SecurityNote(Critical = "Sets critical properties on EnumDataContract.",
1198             Safe = "Called during schema import/code generation.")]
1199         [SecuritySafeCritical]
1200         EnumDataContract ImportEnum(XmlQualifiedName typeName, XmlSchemaSimpleTypeRestriction restriction, bool isFlags, XmlSchemaAnnotation annotation)
1201         {
1202             EnumDataContract dataContract = new EnumDataContract();
1203             dataContract.StableName = typeName;
1204             dataContract.BaseContractName = ImportActualType(annotation, SchemaExporter.DefaultEnumBaseTypeName, typeName);
1205             dataContract.IsFlags = isFlags;
1206             AddDataContract(dataContract);
1207
1208             // CheckIfEnum has already checked if baseType of restriction is string 
1209             dataContract.Values = new List<long>();
1210             dataContract.Members = new List<DataMember>();
1211             foreach (XmlSchemaFacet facet in restriction.Facets)
1212             {
1213                 XmlSchemaEnumerationFacet enumFacet = facet as XmlSchemaEnumerationFacet;
1214                 if (enumFacet == null)
1215                     ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumOnlyEnumerationFacetsSupported));
1216                 if (enumFacet.Value == null)
1217                     ThrowEnumTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.EnumEnumerationFacetsMustHaveValue));
1218
1219                 string valueInnerText = GetInnerText(typeName, ImportAnnotation(enumFacet.Annotation, SchemaExporter.EnumerationValueAnnotationName));
1220                 if (valueInnerText == null)
1221                     dataContract.Values.Add(SchemaExporter.GetDefaultEnumValue(isFlags, dataContract.Members.Count));
1222                 else
1223                     dataContract.Values.Add(dataContract.GetEnumValueFromString(valueInnerText));
1224                 DataMember dataMember = new DataMember(enumFacet.Value);
1225                 dataContract.Members.Add(dataMember);
1226             }
1227             return dataContract;
1228         }
1229
1230         DataContract ImportSimpleTypeRestriction(XmlQualifiedName typeName, XmlSchemaSimpleTypeRestriction restriction)
1231         {
1232             DataContract dataContract = null;
1233
1234             if (!restriction.BaseTypeName.IsEmpty)
1235                 dataContract = ImportType(restriction.BaseTypeName);
1236             else if (restriction.BaseType != null)
1237                 dataContract = ImportType(restriction.BaseType);
1238             else
1239                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SimpleTypeRestrictionDoesNotSpecifyBase));
1240
1241             return dataContract;
1242         }
1243
1244         void ImportDataContractExtension(XmlSchemaType type, DataContract dataContract)
1245         {
1246             if (type.Annotation == null || type.Annotation.Items == null)
1247                 return;
1248             foreach (XmlSchemaObject schemaObject in type.Annotation.Items)
1249             {
1250                 XmlSchemaAppInfo appInfo = schemaObject as XmlSchemaAppInfo;
1251                 if (appInfo == null)
1252                     continue;
1253                 if (appInfo.Markup != null)
1254                 {
1255                     foreach (XmlNode xmlNode in appInfo.Markup)
1256                     {
1257                         XmlElement typeElement = xmlNode as XmlElement;
1258                         XmlQualifiedName surrogateDataAnnotationName = SchemaExporter.SurrogateDataAnnotationName;
1259                         if (typeElement != null && typeElement.NamespaceURI == surrogateDataAnnotationName.Namespace && typeElement.LocalName == surrogateDataAnnotationName.Name)
1260                         {
1261                             object surrogateData = ImportSurrogateData(typeElement, surrogateDataAnnotationName.Name, surrogateDataAnnotationName.Namespace);
1262                             dataContractSet.SetSurrogateData(dataContract, surrogateData);
1263                         }
1264                     }
1265                 }
1266             }
1267         }
1268
1269         [Fx.Tag.SecurityNote(Critical = "Sets critical properties on DataContract.",
1270             Safe = "Called during schema import/code generation.")]
1271         [SecuritySafeCritical]
1272         void ImportGenericInfo(XmlSchemaType type, DataContract dataContract)
1273         {
1274             if (type.Annotation == null || type.Annotation.Items == null)
1275                 return;
1276             foreach (XmlSchemaObject schemaObject in type.Annotation.Items)
1277             {
1278                 XmlSchemaAppInfo appInfo = schemaObject as XmlSchemaAppInfo;
1279                 if (appInfo == null)
1280                     continue;
1281                 if (appInfo.Markup != null)
1282                 {
1283                     foreach (XmlNode xmlNode in appInfo.Markup)
1284                     {
1285                         XmlElement typeElement = xmlNode as XmlElement;
1286                         if (typeElement != null && typeElement.NamespaceURI == Globals.SerializationNamespace)
1287                         {
1288                             if (typeElement.LocalName == Globals.GenericTypeLocalName)
1289                                 dataContract.GenericInfo = ImportGenericInfo(typeElement, type);
1290                         }
1291                     }
1292                 }
1293             }
1294         }
1295
1296         GenericInfo ImportGenericInfo(XmlElement typeElement, XmlSchemaType type)
1297         {
1298             XmlNode nameAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericNameAttribute);
1299             string name = (nameAttribute == null) ? null : nameAttribute.Value;
1300             if (name == null)
1301                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationAttributeNotFound, type.Name, Globals.GenericNameAttribute)));
1302             XmlNode nsAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericNamespaceAttribute);
1303             string ns = (nsAttribute == null) ? null : nsAttribute.Value;
1304             if (ns == null)
1305                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationAttributeNotFound, type.Name, Globals.GenericNamespaceAttribute)));
1306             if (typeElement.ChildNodes.Count > 0) //Generic Type
1307                 name = DataContract.EncodeLocalName(name);
1308
1309             int currentLevel = 0;
1310             GenericInfo genInfo = new GenericInfo(new XmlQualifiedName(name, ns), type.Name);
1311             foreach (XmlNode childNode in typeElement.ChildNodes)
1312             {
1313                 XmlElement argumentElement = childNode as XmlElement;
1314                 if (argumentElement == null)
1315                     continue;
1316                 if (argumentElement.LocalName != Globals.GenericParameterLocalName ||
1317                     argumentElement.NamespaceURI != Globals.SerializationNamespace)
1318                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationHasInvalidElement, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name)));
1319                 XmlNode nestedLevelAttribute = argumentElement.Attributes.GetNamedItem(Globals.GenericParameterNestedLevelAttribute);
1320                 int argumentLevel = 0;
1321                 if (nestedLevelAttribute != null)
1322                 {
1323                     if (!Int32.TryParse(nestedLevelAttribute.Value, out argumentLevel))
1324                         throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationHasInvalidAttributeValue, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name, nestedLevelAttribute.Value, nestedLevelAttribute.LocalName, Globals.TypeOfInt.Name)));
1325                 }
1326                 if (argumentLevel < currentLevel)
1327                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationForNestedLevelMustBeIncreasing, argumentElement.LocalName, argumentElement.NamespaceURI, type.Name)));
1328                 genInfo.Add(ImportGenericInfo(argumentElement, type));
1329                 genInfo.AddToLevel(argumentLevel, 1);
1330                 currentLevel = argumentLevel;
1331             }
1332
1333             XmlNode typeNestedLevelsAttribute = typeElement.Attributes.GetNamedItem(Globals.GenericParameterNestedLevelAttribute);
1334             if (typeNestedLevelsAttribute != null)
1335             {
1336                 int nestedLevels = 0;
1337                 if (!Int32.TryParse(typeNestedLevelsAttribute.Value, out nestedLevels))
1338                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericAnnotationHasInvalidAttributeValue, typeElement.LocalName, typeElement.NamespaceURI, type.Name, typeNestedLevelsAttribute.Value, typeNestedLevelsAttribute.LocalName, Globals.TypeOfInt.Name)));
1339                 if ((nestedLevels - 1) > currentLevel)
1340                     genInfo.AddToLevel(nestedLevels - 1, 0);
1341             }
1342             return genInfo;
1343         }
1344
1345         object ImportSurrogateData(XmlElement typeElement, string name, string ns)
1346         {
1347             if (dataContractSet.DataContractSurrogate != null && typeElement != null)
1348             {
1349                 Collection<Type> knownTypes = new Collection<Type>();
1350                 DataContractSurrogateCaller.GetKnownCustomDataTypes(dataContractSet.DataContractSurrogate, knownTypes);
1351                 DataContractSerializer serializer = new DataContractSerializer(Globals.TypeOfObject, name, ns, knownTypes,
1352                     Int32.MaxValue, false /*ignoreExtensionDataObject*/, true /*preserveObjectReferences*/, null /*dataContractSurrogate*/);
1353                 return serializer.ReadObject(new XmlNodeReader(typeElement));
1354             }
1355             return null;
1356         }
1357
1358         void CheckComplexType(XmlQualifiedName typeName, XmlSchemaComplexType type)
1359         {
1360             if (type.IsAbstract)
1361                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AbstractTypeNotSupported));
1362             if (type.IsMixed)
1363                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.MixedContentNotSupported));
1364         }
1365
1366         void CheckIfElementUsesUnsupportedConstructs(XmlQualifiedName typeName, XmlSchemaElement element)
1367         {
1368             if (element.IsAbstract)
1369                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AbstractElementNotSupported, element.Name));
1370             if (element.DefaultValue != null)
1371                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.DefaultOnElementNotSupported, element.Name));
1372             if (element.FixedValue != null)
1373                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.FixedOnElementNotSupported, element.Name));
1374             if (!element.SubstitutionGroup.IsEmpty)
1375                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.SubstitutionGroupOnElementNotSupported, element.Name));
1376         }
1377
1378         void ImportAttributes(XmlQualifiedName typeName, XmlSchemaObjectCollection attributes, XmlSchemaAnyAttribute anyAttribute, out bool isReference)
1379         {
1380             if (anyAttribute != null)
1381                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.AnyAttributeNotSupported));
1382
1383             isReference = false;
1384             if (attributes != null)
1385             {
1386                 bool foundId = false, foundRef = false;
1387                 for (int i = 0; i < attributes.Count; i++)
1388                 {
1389                     XmlSchemaObject o = attributes[i];
1390                     if (o is XmlSchemaAttribute)
1391                     {
1392                         XmlSchemaAttribute attribute = (XmlSchemaAttribute)o;
1393                         if (attribute.Use == XmlSchemaUse.Prohibited)
1394                             continue;
1395                         if (TryCheckIfAttribute(typeName, attribute, Globals.IdQualifiedName, ref foundId))
1396                             continue;
1397                         if (TryCheckIfAttribute(typeName, attribute, Globals.RefQualifiedName, ref foundRef))
1398                             continue;
1399                         if (attribute.RefName.IsEmpty || attribute.RefName.Namespace != Globals.SerializationNamespace || attribute.Use == XmlSchemaUse.Required)
1400                             ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.TypeShouldNotContainAttributes, Globals.SerializationNamespace));
1401                     }
1402                 }
1403                 isReference = (foundId && foundRef);
1404             }
1405         }
1406
1407         bool TryCheckIfAttribute(XmlQualifiedName typeName, XmlSchemaAttribute attribute, XmlQualifiedName refName, ref bool foundAttribute)
1408         {
1409             if (attribute.RefName != refName)
1410                 return false;
1411             if (foundAttribute)
1412                 ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.CannotHaveDuplicateAttributeNames, refName.Name));
1413             foundAttribute = true;
1414             return true;
1415         }
1416
1417         void AddDataContract(DataContract dataContract)
1418         {
1419             dataContractSet.Add(dataContract.StableName, dataContract);
1420         }
1421
1422         string GetInnerText(XmlQualifiedName typeName, XmlElement xmlElement)
1423         {
1424             if (xmlElement != null)
1425             {
1426                 XmlNode child = xmlElement.FirstChild;
1427                 while (child != null)
1428                 {
1429                     if (child.NodeType == XmlNodeType.Element)
1430                         ThrowTypeCannotBeImportedException(typeName.Name, typeName.Namespace, SR.GetString(SR.InvalidAnnotationExpectingText, xmlElement.LocalName, xmlElement.NamespaceURI, child.LocalName, child.NamespaceURI));
1431                     child = child.NextSibling;
1432                 }
1433                 return xmlElement.InnerText;
1434             }
1435             return null;
1436         }
1437
1438         static XmlElement ImportAnnotation(XmlSchemaAnnotation annotation, XmlQualifiedName annotationQualifiedName)
1439         {
1440             if (annotation != null && annotation.Items != null && annotation.Items.Count > 0 && annotation.Items[0] is XmlSchemaAppInfo)
1441             {
1442                 XmlSchemaAppInfo appInfo = (XmlSchemaAppInfo)annotation.Items[0];
1443                 XmlNode[] markup = appInfo.Markup;
1444                 if (markup != null)
1445                 {
1446                     for (int i = 0; i < markup.Length; i++)
1447                     {
1448                         XmlElement annotationElement = markup[i] as XmlElement;
1449                         if (annotationElement != null && annotationElement.LocalName == annotationQualifiedName.Name && annotationElement.NamespaceURI == annotationQualifiedName.Namespace)
1450                             return annotationElement;
1451                     }
1452                 }
1453             }
1454             return null;
1455         }
1456
1457         static void ThrowTypeCannotBeImportedException(string name, string ns, string message)
1458         {
1459             ThrowTypeCannotBeImportedException(SR.GetString(SR.TypeCannotBeImported, name, ns, message));
1460         }
1461
1462         static void ThrowArrayTypeCannotBeImportedException(string name, string ns, string message)
1463         {
1464             ThrowTypeCannotBeImportedException(SR.GetString(SR.ArrayTypeCannotBeImported, name, ns, message));
1465         }
1466
1467         static void ThrowEnumTypeCannotBeImportedException(string name, string ns, string message)
1468         {
1469             ThrowTypeCannotBeImportedException(SR.GetString(SR.EnumTypeCannotBeImported, name, ns, message));
1470         }
1471
1472         static void ThrowISerializableTypeCannotBeImportedException(string name, string ns, string message)
1473         {
1474             ThrowTypeCannotBeImportedException(SR.GetString(SR.ISerializableTypeCannotBeImported, name, ns, message));
1475         }
1476
1477         static void ThrowTypeCannotBeImportedException(string message)
1478         {
1479             throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeCannotBeImportedHowToFix, message)));
1480         }
1481     }
1482
1483 }
1484
1485