svn path=/branches/mono-1-1-9/mcs/; revision=51207
[mono.git] / mcs / class / System.XML / System.Xml.Serialization / MapCodeGenerator.cs
1 // 
2 // System.Xml.Serialization.MapCodeGenerator 
3 //
4 // Author:
5 //   Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // Copyright (C) Ximian, Inc., 2003
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.CodeDom;
32 using System.CodeDom.Compiler;
33 using System.Collections;
34 using System.Globalization;
35 using System.Xml.Schema;
36
37 namespace System.Xml.Serialization {
38         internal class MapCodeGenerator {
39
40                 CodeNamespace codeNamespace;
41                 CodeCompileUnit codeCompileUnit;
42                 CodeAttributeDeclarationCollection includeMetadata;
43                 XmlTypeMapping exportedAnyType = null;
44                 protected bool includeArrayTypes;
45                 ICodeGenerator codeGen;
46                 CodeGenerationOptions options;
47
48                 Hashtable exportedMaps = new Hashtable ();
49                 Hashtable includeMaps = new Hashtable ();
50
51                 public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit)
52                 {
53                         this.codeCompileUnit = codeCompileUnit;
54                         this.codeNamespace = codeNamespace;
55                         this.options = CodeGenerationOptions.GenerateOldAsync;
56                 }
57
58                 public MapCodeGenerator (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, ICodeGenerator codeGen, CodeGenerationOptions options, Hashtable mappings)
59                 {
60                         this.codeCompileUnit = codeCompileUnit;
61                         this.codeNamespace = codeNamespace;
62                         this.codeGen = codeGen;
63                         this.options = options;
64 //                      this.mappings = mappings;
65                 }
66
67                 public CodeAttributeDeclarationCollection IncludeMetadata 
68                 {
69                         get 
70                         { 
71                                 if (includeMetadata != null) return includeMetadata;
72                                 includeMetadata = new CodeAttributeDeclarationCollection ();
73                                 
74                                 foreach (XmlTypeMapping map in includeMaps.Values)
75                                         GenerateClassInclude (includeMetadata, map);
76                                 
77                                 return includeMetadata; 
78                         }
79                 }
80                 
81                 #region Code generation methods
82
83                 public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)
84                 {
85                         CodeTypeDeclaration dummyClass = new CodeTypeDeclaration ();
86                         ExportMembersMapCode (dummyClass, (ClassMap)xmlMembersMapping.ObjectMap, xmlMembersMapping.Namespace, null);
87                 }
88
89                 public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
90                 {
91                         ExportMapCode (xmlTypeMapping);
92                         RemoveInclude (xmlTypeMapping);
93                 }
94
95                 void ExportMapCode (XmlTypeMapping map)
96                 {
97                         switch (map.TypeData.SchemaType)
98                         {
99                                 case SchemaTypes.Enum:
100                                         ExportEnumCode (map);
101                                         break;
102
103                                 case SchemaTypes.Array:
104                                         ExportArrayCode (map);
105                                         break;
106
107                                 case SchemaTypes.Class:
108                                         ExportClassCode (map);
109                                         break;
110
111                                 case SchemaTypes.XmlSerializable:
112                                 case SchemaTypes.XmlNode:
113                                 case SchemaTypes.Primitive:
114                                         // Ignore
115                                         break;
116                         }
117                 }
118
119                 void ExportClassCode (XmlTypeMapping map)
120                 {
121                         CodeTypeDeclaration codeClass;
122                         
123                         if (IsMapExported (map)) {
124                                 // Regenerate attributes, since things may have changed
125                                 codeClass = GetMapDeclaration (map);
126                                 if (codeClass != null) {
127                                         codeClass.CustomAttributes = null;
128                                         GenerateClass (map, codeClass);
129                                         ExportDerivedTypeAttributes (map, codeClass);
130                                 }
131                                 return;
132                         }
133
134                         if (map.TypeData.Type == typeof(object))
135                         {
136                                 exportedAnyType = map;
137                                 SetMapExported (map, null);
138                                 foreach (XmlTypeMapping dmap in exportedAnyType.DerivedTypes) {
139                                         if (IsMapExported (dmap) || !dmap.IncludeInSchema) continue;
140                                         ExportTypeMapping (dmap);
141                                         AddInclude (dmap);
142                                 }
143                                 return;
144                         }
145                         
146                         codeClass = new CodeTypeDeclaration (map.TypeData.TypeName);
147                         SetMapExported (map, codeClass);
148
149                         AddCodeType (codeClass, map.Documentation);
150                         codeClass.Attributes = MemberAttributes.Public;
151
152                         GenerateClass (map, codeClass);
153                         ExportDerivedTypeAttributes (map, codeClass);
154                         
155                         ExportMembersMapCode (codeClass, (ClassMap)map.ObjectMap, map.XmlTypeNamespace, map.BaseMap);
156
157                         if (map.BaseMap != null && map.BaseMap.TypeData.SchemaType != SchemaTypes.XmlNode)
158                         {
159                                 CodeTypeReference ctr = new CodeTypeReference (map.BaseMap.TypeData.FullTypeName);
160                                 codeClass.BaseTypes.Add (ctr);
161                                 if (map.BaseMap.IncludeInSchema) {
162                                         ExportMapCode (map.BaseMap);
163                                         AddInclude (map.BaseMap);
164                                 }
165                         }
166                         ExportDerivedTypes (map, codeClass);
167                 }
168                 
169                 void ExportDerivedTypeAttributes (XmlTypeMapping map, CodeTypeDeclaration codeClass)
170                 {
171                         foreach (XmlTypeMapping tm in map.DerivedTypes)
172                         {
173                                 GenerateClassInclude (codeClass.CustomAttributes, tm);
174                                 ExportDerivedTypeAttributes (tm, codeClass);
175                         }
176                 }
177
178                 void ExportDerivedTypes (XmlTypeMapping map, CodeTypeDeclaration codeClass)
179                 {
180                         foreach (XmlTypeMapping tm in map.DerivedTypes)
181                         {
182                                 if (codeClass.CustomAttributes == null) 
183                                         codeClass.CustomAttributes = new CodeAttributeDeclarationCollection ();
184
185                                 ExportMapCode (tm);
186                                 ExportDerivedTypes (tm, codeClass);
187                         }
188                 }
189
190                 void ExportMembersMapCode (CodeTypeDeclaration codeClass, ClassMap map, string defaultNamespace, XmlTypeMapping baseMap)
191                 {
192                         ICollection members = map.ElementMembers;
193                                 
194                         if (members != null)
195                         {
196                                 foreach (XmlTypeMapMemberElement member in members)
197                                 {
198                                         if (baseMap != null && DefinedInBaseMap (baseMap, member)) continue;
199
200                                         Type memType = member.GetType();
201                                         if (memType == typeof(XmlTypeMapMemberList))
202                                         {
203                                                 AddArrayElementFieldMember (codeClass, (XmlTypeMapMemberList) member, defaultNamespace);
204                                         }
205                                         else if (memType == typeof(XmlTypeMapMemberFlatList))
206                                         {
207                                                 AddElementFieldMember (codeClass, member, defaultNamespace);
208                                         }
209                                         else if (memType == typeof(XmlTypeMapMemberAnyElement))
210                                         {
211                                                 AddAnyElementFieldMember (codeClass, member, defaultNamespace);
212                                         }
213                                         else if (memType == typeof(XmlTypeMapMemberElement))
214                                         {
215                                                 AddElementFieldMember (codeClass, member, defaultNamespace);
216                                         }
217                                         else
218                                         {
219                                                 throw new InvalidOperationException ("Member type " + memType + " not supported");
220                                         }
221                                 }
222                         }
223
224                         // Write attributes
225
226                         ICollection attributes = map.AttributeMembers;
227                         if (attributes != null)
228                         {
229                                 foreach (XmlTypeMapMemberAttribute attr in attributes) {
230                                         if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
231                                         AddAttributeFieldMember (codeClass, attr, defaultNamespace);
232                                 }
233                         }
234
235                         XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
236                         if (anyAttrMember != null)
237                         {
238                                 CodeTypeMember codeField = CreateFieldMember (codeClass, anyAttrMember.TypeData, anyAttrMember.Name);
239                                 AddComments (codeField, anyAttrMember.Documentation);
240                                 codeField.Attributes = MemberAttributes.Public;
241                                 GenerateAnyAttribute (codeField);
242                         }
243                 }
244                 
245                 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, Type type, string name)
246                 {
247                         return CreateFieldMember (codeClass, new CodeTypeReference(type), name, System.DBNull.Value, null, null);
248                 }
249
250                 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, TypeData type, string name)
251                 {
252                         return CreateFieldMember (codeClass, GetDomType (type), name, System.DBNull.Value, null, null);
253                 }
254
255                 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMember member)
256                 {
257                         return CreateFieldMember (codeClass, GetDomType (member.TypeData), member.Name, member.DefaultValue, member.TypeData, member.Documentation);
258                 }
259                 
260                 CodeTypeMember CreateFieldMember (CodeTypeDeclaration codeClass, CodeTypeReference type, string name, object defaultValue, TypeData defaultType, string documentation)
261                 {
262                         CodeMemberField codeField = null;
263                         CodeTypeMember codeProp = null;
264                         
265                         if ((options & CodeGenerationOptions.GenerateProperties) > 0) {
266                                 string field = CodeIdentifier.MakeCamel (name + "Field");
267                                 codeField = new CodeMemberField (type, field);
268                                 codeField.Attributes = MemberAttributes.Private;
269                                 codeClass.Members.Add (codeField);
270                                 
271                                 CodeMemberProperty prop = new CodeMemberProperty ();
272                                 prop.Name = name;
273                                 prop.Type = type;
274                                 prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
275                                 codeProp = prop;
276                                 prop.HasGet = prop.HasSet = true;
277                                 
278                                 CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), field);
279                                 prop.SetStatements.Add (new CodeAssignStatement (ce, new CodePropertySetValueReferenceExpression()));
280                                 prop.GetStatements.Add (new CodeMethodReturnStatement (ce));
281                         }
282                         else {
283                                 codeField = new CodeMemberField (type, name);
284                                 codeField.Attributes = MemberAttributes.Public;
285                                 codeProp = codeField;
286                         }
287                         
288                         if (defaultValue != System.DBNull.Value)
289                                 GenerateDefaultAttribute (codeField, codeProp, defaultType, defaultValue);
290
291                         AddComments (codeProp, documentation);
292                         codeClass.Members.Add (codeProp);
293                         return codeProp;
294                 }
295
296                 void AddAttributeFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberAttribute attinfo, string defaultNamespace)
297                 {
298                         CodeTypeMember codeField = CreateFieldMember (codeClass, attinfo);
299
300                         CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
301                         if (attributes == null) attributes = new CodeAttributeDeclarationCollection ();
302                         
303                         GenerateAttributeMember (attributes, attinfo, defaultNamespace, false);
304                         if (attributes.Count > 0) codeField.CustomAttributes = attributes;
305
306                         if (attinfo.MappedType != null) {
307                                 ExportMapCode (attinfo.MappedType);
308                                 RemoveInclude (attinfo.MappedType);
309                         }
310
311                         if (attinfo.TypeData.IsValueType && attinfo.IsOptionalValueType)
312                         {
313                                 codeField = CreateFieldMember (codeClass, typeof(bool), attinfo.Name + "Specified");
314                                 codeField.Attributes = MemberAttributes.Public;
315                                 GenerateSpecifierMember (codeField);
316                         }
317                 }
318                 
319                 public void AddAttributeMemberAttributes (XmlTypeMapMemberAttribute attinfo, string defaultNamespace, CodeAttributeDeclarationCollection attributes, bool forceUseMemberName)
320                 {
321                         GenerateAttributeMember (attributes, attinfo, defaultNamespace, forceUseMemberName);
322                 }
323
324                 void AddElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
325                 {
326                         CodeTypeMember codeField = CreateFieldMember (codeClass, member);
327                         
328                         CodeAttributeDeclarationCollection attributes = codeField.CustomAttributes;
329                         if (attributes == null) attributes = new CodeAttributeDeclarationCollection ();
330                         
331                         AddElementMemberAttributes (member, defaultNamespace, attributes, false);
332                         if (attributes.Count > 0) codeField.CustomAttributes = attributes;
333                         
334                         if (member.TypeData.IsValueType && member.IsOptionalValueType)
335                         {
336                                 codeField = CreateFieldMember (codeClass, typeof(bool), member.Name + "Specified");
337                                 codeField.Attributes = MemberAttributes.Public;
338                                 GenerateSpecifierMember (codeField);
339                         }
340                 }
341
342                 public void AddElementMemberAttributes (XmlTypeMapMemberElement member, string defaultNamespace, CodeAttributeDeclarationCollection attributes, bool forceUseMemberName)
343                 {
344                         TypeData defaultType = member.TypeData;
345                         bool addAlwaysAttr = false;
346                         
347                         if (member is XmlTypeMapMemberFlatList)
348                         {
349                                 defaultType = defaultType.ListItemTypeData;
350                                 addAlwaysAttr = true;
351                         }
352                         
353                         foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)
354                         {
355                                 if (ExportExtraElementAttributes (attributes, einfo, defaultNamespace, defaultType))
356                                         continue;
357
358                                 GenerateElementInfoMember (attributes, member, einfo, defaultType, defaultNamespace, addAlwaysAttr, forceUseMemberName);
359                                 if (einfo.MappedType != null) {
360                                         ExportMapCode (einfo.MappedType);
361                                         RemoveInclude (einfo.MappedType);
362                                 }
363                         }
364
365                         GenerateElementMember (attributes, member);
366                 }
367
368                 void AddAnyElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
369                 {
370                         CodeTypeMember codeField = CreateFieldMember (codeClass, member);
371
372                         CodeAttributeDeclarationCollection attributes = new CodeAttributeDeclarationCollection ();
373                         foreach (XmlTypeMapElementInfo einfo in member.ElementInfo)
374                                 ExportExtraElementAttributes (attributes, einfo, defaultNamespace, einfo.TypeData);
375                                 
376                         if (attributes.Count > 0) codeField.CustomAttributes = attributes;
377                 }
378
379                 bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
380                 {
381                         if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
382                                 return true;
383                         else if (map.BaseMap != null)
384                                 return DefinedInBaseMap (map.BaseMap, member);
385                         else
386                                 return false;
387                 }
388
389                 void AddArrayElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberList member, string defaultNamespace)
390                 {
391                         CodeTypeMember codeField = CreateFieldMember (codeClass, member.TypeData, member.Name);
392                         codeField.Attributes = MemberAttributes.Public;
393                         
394                         CodeAttributeDeclarationCollection attributes = new CodeAttributeDeclarationCollection ();
395                         AddArrayAttributes (attributes, member, defaultNamespace, false);
396
397                         ListMap listMap = (ListMap) member.ListTypeMapping.ObjectMap;
398                         AddArrayItemAttributes (attributes, listMap, member.TypeData.ListItemTypeData, defaultNamespace, 0);
399                         
400                         if (attributes.Count > 0) codeField.CustomAttributes = attributes;
401                 }
402
403                 public void AddArrayAttributes (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, string defaultNamespace, bool forceUseMemberName)
404                 {
405                         GenerateArrayElement (attributes, member, defaultNamespace, forceUseMemberName);
406                 }
407
408                 public void AddArrayItemAttributes (CodeAttributeDeclarationCollection attributes, ListMap listMap, TypeData type, string defaultNamespace, int nestingLevel)
409                 {
410                         foreach (XmlTypeMapElementInfo ainfo in listMap.ItemInfo)
411                         {
412                                 string defaultName;
413                                 if (ainfo.MappedType != null) defaultName = ainfo.MappedType.ElementName;
414                                 else defaultName = ainfo.TypeData.XmlType;
415
416                                 GenerateArrayItemAttributes (attributes, listMap, type, ainfo, defaultName, defaultNamespace, nestingLevel);
417                                 if (ainfo.MappedType != null) {
418                                         if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
419                                                 AddInclude (ainfo.MappedType);
420                                         ExportMapCode (ainfo.MappedType);
421                                 }
422                         }
423
424                         if (listMap.IsMultiArray)
425                         {
426                                 XmlTypeMapping nmap = listMap.NestedArrayMapping;
427                                 AddArrayItemAttributes (attributes, (ListMap) nmap.ObjectMap, nmap.TypeData.ListItemTypeData, defaultNamespace, nestingLevel + 1);
428                         }
429                 }
430                 
431                 void ExportArrayCode (XmlTypeMapping map)
432                 {
433                         ListMap listMap = (ListMap) map.ObjectMap;
434                         foreach (XmlTypeMapElementInfo ainfo in listMap.ItemInfo)
435                         {
436                                 if (ainfo.MappedType != null) {
437                                         if (!IsMapExported (ainfo.MappedType) && includeArrayTypes)
438                                                 AddInclude (ainfo.MappedType);
439                                         ExportMapCode (ainfo.MappedType);
440                                 }
441                         }
442                 }
443
444                 bool ExportExtraElementAttributes (CodeAttributeDeclarationCollection attributes, XmlTypeMapElementInfo einfo, string defaultNamespace, TypeData defaultType)
445                 {
446                         if (einfo.IsTextElement) {
447                                 GenerateTextElementAttribute (attributes, einfo, defaultType);
448                                 return true;
449                         }
450                         else if (einfo.IsUnnamedAnyElement) {
451                                 GenerateUnnamedAnyElementAttribute (attributes, einfo, defaultNamespace);
452                                 return true;
453                         }
454                         return false;
455                 }
456
457                 void ExportEnumCode (XmlTypeMapping map)
458                 {
459                         if (IsMapExported (map)) return;
460
461                         CodeTypeDeclaration codeEnum = new CodeTypeDeclaration (map.TypeData.TypeName);
462                         SetMapExported (map, codeEnum);
463                         
464                         codeEnum.Attributes = MemberAttributes.Public;
465                         codeEnum.IsEnum = true;
466                         AddCodeType (codeEnum, map.Documentation);
467
468                         GenerateEnum (map, codeEnum);
469                         EnumMap emap = (EnumMap) map.ObjectMap;
470                         
471                         if (emap.IsFlags)
472                                 codeEnum.CustomAttributes.Add (new CodeAttributeDeclaration ("System.Flags"));
473
474                         int flag = 1;
475                         foreach (EnumMap.EnumMapMember emem in emap.Members)
476                         {
477                                 CodeMemberField codeField = new CodeMemberField ("", emem.EnumName);
478                                 if (emap.IsFlags) {
479                                         codeField.InitExpression = new CodePrimitiveExpression (flag);
480                                         flag *= 2;
481                                 }
482                                 
483                                 AddComments (codeField, emem.Documentation);
484
485                                 GenerateEnumItem (codeField, emem);
486                                 codeEnum.Members.Add (codeField);
487                         }
488                 }
489                 
490                 void AddInclude (XmlTypeMapping map)
491                 {
492                         if (!includeMaps.ContainsKey (map.TypeData.FullTypeName))
493                                 includeMaps [map.TypeData.FullTypeName] = map;
494                 }
495
496                 void RemoveInclude (XmlTypeMapping map)
497                 {
498                         includeMaps.Remove (map.TypeData.FullTypeName);
499                 }
500
501                 #endregion
502                 
503                 #region Helper methods
504                 
505                 bool IsMapExported (XmlTypeMapping map)
506                 {
507                         if (exportedMaps.Contains (map.TypeData.FullTypeName)) return true;
508                         return false;
509                 }
510
511                 void SetMapExported (XmlTypeMapping map, CodeTypeDeclaration declaration)
512                 {
513                         exportedMaps.Add (map.TypeData.FullTypeName, declaration);
514                 }
515
516                 CodeTypeDeclaration GetMapDeclaration (XmlTypeMapping map)
517                 {
518                         return exportedMaps [map.TypeData.FullTypeName] as CodeTypeDeclaration;
519                 }
520
521                 public static void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)
522                 {
523                         if (att.Arguments.Count == 0 && !addIfNoParams) return;
524                         
525                         if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
526                         ctm.CustomAttributes.Add (att);
527                 }
528
529                 public static void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)
530                 {
531                         if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
532                         ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));
533                 }
534
535                 public static CodeAttributeArgument GetArg (string name, object value)
536                 {
537                         return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));
538                 }
539
540                 public static CodeAttributeArgument GetArg (object value)
541                 {
542                         return new CodeAttributeArgument (new CodePrimitiveExpression(value));
543                 }
544
545                 public static CodeAttributeArgument GetTypeArg (string name, string typeName)
546                 {
547                         return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));
548                 }
549
550                 public static CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)
551                 {
552                         return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));
553                 }
554                 
555                 public static void AddComments (CodeTypeMember member, string comments)
556                 {
557                         if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
558                         else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
559                 }
560
561                 void AddCodeType (CodeTypeDeclaration type, string comments)
562                 {
563                         AddComments (type, comments);
564                         codeNamespace.Types.Add (type);
565                 }
566                 
567                 CodeTypeReference GetDomType (TypeData data)
568                 {
569                         if (data.SchemaType == SchemaTypes.Array)
570                                 return new CodeTypeReference (GetDomType (data.ListItemTypeData),1);
571                         else
572                                 return new CodeTypeReference (data.FullTypeName);
573                 }
574                 
575                 #endregion
576                 
577                 #region Overridable methods
578                 
579                 protected virtual void GenerateClass (XmlTypeMapping map, CodeTypeDeclaration codeClass)
580                 {
581                 }
582                 
583                 protected virtual void GenerateClassInclude (CodeAttributeDeclarationCollection attributes, XmlTypeMapping map)
584                 {
585                 }
586                 
587                 protected virtual void GenerateAnyAttribute (CodeTypeMember codeField)
588                 {
589                 }
590                 
591                 protected virtual void GenerateDefaultAttribute (CodeMemberField internalField, CodeTypeMember externalField, TypeData typeData, object defaultValue)
592                 {
593                         if (typeData.Type == null)
594                         {
595                                 // It must be an enumeration defined in the schema.
596                                 if (typeData.SchemaType != SchemaTypes.Enum) 
597                                         throw new InvalidOperationException ("Type " + typeData.TypeName + " not supported");
598
599                                 IFormattable defaultValueFormattable = defaultValue as IFormattable;
600                                 CodeFieldReferenceExpression fref = new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typeData.FullTypeName), defaultValueFormattable != null ? defaultValueFormattable.ToString(null, CultureInfo.InvariantCulture) : defaultValue.ToString ());
601                                 CodeAttributeArgument arg = new CodeAttributeArgument (fref);
602                                 AddCustomAttribute (externalField, "System.ComponentModel.DefaultValue", arg);
603                                 internalField.InitExpression = fref;
604                         }
605                         else
606                         {
607                                 AddCustomAttribute (externalField, "System.ComponentModel.DefaultValue", GetArg (defaultValue));
608                                 internalField.InitExpression = new CodePrimitiveExpression (defaultValue);
609                         }
610                 }
611                 
612                 protected virtual void GenerateAttributeMember (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberAttribute attinfo, string defaultNamespace, bool forceUseMemberName)
613                 {
614                 }
615                 
616                 protected virtual void GenerateElementInfoMember (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, XmlTypeMapElementInfo einfo, TypeData defaultType, string defaultNamespace, bool addAlwaysAttr, bool forceUseMemberName)
617                 {
618                 }
619                 
620                 protected virtual void GenerateElementMember (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member)
621                 {
622                 }
623                 
624                 protected virtual void GenerateArrayElement (CodeAttributeDeclarationCollection attributes, XmlTypeMapMemberElement member, string defaultNamespace, bool forceUseMemberName)
625                 {
626                 }
627                 
628                 protected virtual void GenerateArrayItemAttributes (CodeAttributeDeclarationCollection attributes, ListMap listMap, TypeData type, XmlTypeMapElementInfo ainfo, string defaultName, string defaultNamespace, int nestingLevel)
629                 {
630                 }
631
632                 protected virtual void GenerateTextElementAttribute (CodeAttributeDeclarationCollection attributes, XmlTypeMapElementInfo einfo, TypeData defaultType)
633                 {
634                 }
635                 
636                 protected virtual void GenerateUnnamedAnyElementAttribute (CodeAttributeDeclarationCollection attributes, XmlTypeMapElementInfo einfo, string defaultNamespace)
637                 {
638                 }
639                 
640                 protected virtual void GenerateEnum (XmlTypeMapping map, CodeTypeDeclaration codeEnum)
641                 {
642                 }               
643                 
644                 protected virtual void GenerateEnumItem (CodeMemberField codeField, EnumMap.EnumMapMember emem)
645                 {
646                 }
647
648                 protected virtual void GenerateSpecifierMember (CodeTypeMember codeField)
649                 {
650                 }
651
652                 #endregion
653         }
654 }