@@ -13,6 +13,112 @@ namespace DocumentFormat.OpenXml.Generator.Generators.Elements;
1313
1414public static class DataModelWriterExtensions
1515{
16+ public static class AttributeStrings
17+ {
18+ public const string ObsoletePropertyWarn = "[Obsolete(\" Unused property, will be removed in a future version.\" , false)]" ;
19+ public const string ObsoletePropertyError = "[Obsolete(\" Unused property, will be removed in a future version.\" , true)]" ;
20+ public const string ObsoleteAttributeWarn = "[Obsolete(\" Unused attribute, will be removed in a future version.\" , false)]" ;
21+ public const string ObsoleteAttributeError = "[Obsolete(\" Unused attribute, will be removed in a future version.\" , true)]" ;
22+ public const string EditorBrowsableAlways = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)] " ;
23+ public const string EditorBrowsableAdvanced = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)] " ;
24+ public const string EditorBrowsableNever = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] " ;
25+ }
26+
27+ private static readonly List < string > ObsoletePropertyWarnList =
28+ [
29+ AttributeStrings . ObsoletePropertyWarn ,
30+ AttributeStrings . EditorBrowsableNever ,
31+ ] ;
32+
33+ // Use this dictionary to add attributes like ObsoleteAttribute or other directives to classes, child elements or attributes.
34+ private static readonly Dictionary < TypedQName , Dictionary < TypedQName , List < string > > > _attributeData =
35+ new Dictionary < TypedQName , Dictionary < TypedQName , List < string > > > ( )
36+ {
37+ // Example with annotations:
38+ // {
39+ // This is the containing complex type class, in the json metadata, this comes from the fully qualified "Name": "c:CT_BubbleSer/c15:ser",
40+ // "c:CT_BubbleSer/c15:ser",
41+ // new Dictionary<TypedQName, List<string>>()
42+ // {
43+ // {
44+ // This is an example of obsoleting the whole class.
45+ // In the json metadata:
46+ // Use the same fully qualified name as the class, for example "Name": "c:CT_BubbleSer/c15:ser",
47+ // "c:CT_BubbleSer/c15:ser",
48+ // ObsoleteClassErrorList
49+ // },
50+ // {
51+ // This is an example obsoleting a child element (property in C#)
52+ // In the json metadata:
53+ // For child elements, this comes from "Name": "c:CT_PictureOptions/c:pictureOptions",
54+ // "c:CT_PictureOptions/c:pictureOptions",
55+ // ObsoletePropertyWarnList
56+ // },
57+ // {
58+ // This is an example obsoleting a child attribute (property in C#)
59+ // In the json metadata: use for example "QName" converted to a TypedQName string using the C# type from the
60+ // Type property with no prefix: ":StringValue/:formatCode",
61+ // ":StringValue/:formatCode",
62+ // ObsoleteAttributeWarnList
63+ // },
64+ // }
65+ // },
66+ {
67+ "c:CT_BubbleSer/c15:ser" ,
68+ new Dictionary < TypedQName , List < string > > ( )
69+ {
70+ {
71+ "c:CT_PictureOptions/c:pictureOptions" ,
72+ ObsoletePropertyWarnList
73+ } ,
74+ }
75+ } ,
76+ {
77+ "c:CT_LineSer/c15:ser" ,
78+ new Dictionary < TypedQName , List < string > > ( )
79+ {
80+ {
81+ "c:CT_PictureOptions/c:pictureOptions" ,
82+ ObsoletePropertyWarnList
83+ } ,
84+ }
85+ } ,
86+ {
87+ "c:CT_PieSer/c15:ser" ,
88+ new Dictionary < TypedQName , List < string > > ( )
89+ {
90+ {
91+ "c:CT_PictureOptions/c:pictureOptions" ,
92+ ObsoletePropertyWarnList
93+ } ,
94+ }
95+ } ,
96+ {
97+ "c:CT_RadarSer/c15:ser" ,
98+ new Dictionary < TypedQName , List < string > > ( )
99+ {
100+ {
101+ "c:CT_PictureOptions/c:pictureOptions" ,
102+ ObsoletePropertyWarnList
103+ } ,
104+ }
105+ } ,
106+ {
107+ "c:CT_SurfaceSer/c15:ser" ,
108+ new Dictionary < TypedQName , List < string > > ( )
109+ {
110+ {
111+ "c:CT_PictureOptions/c:pictureOptions" ,
112+ ObsoletePropertyWarnList
113+ } ,
114+ {
115+ "c:CT_Boolean/c:bubble3D" ,
116+ ObsoletePropertyWarnList
117+ } ,
118+ }
119+ } ,
120+ } ;
121+
16122 public static bool GetDataModelSyntax ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaNamespace model )
17123 {
18124 foreach ( var ns in GetNamespaces ( model , services ) . Distinct ( ) . OrderBy ( n => n ) )
@@ -84,6 +190,20 @@ private static void WriteTypeDetails(this IndentedTextWriter writer, OpenXmlGene
84190 private static void WriteType ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType element )
85191 {
86192 writer . WriteDocumentationComment ( BuildTypeComments ( services , element ) ) ;
193+
194+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > ctAttributeData ) )
195+ {
196+ // if the fully qualified CT/tag name is also one of the children of the dictionary that means the attributes of that
197+ // child's list need to be applied to the whole class, for example, if we're obsoleting an entire class.
198+ if ( ctAttributeData . TryGetValue ( element . Name , out List < string > attributeStrings ) )
199+ {
200+ foreach ( string attributeString in attributeStrings )
201+ {
202+ writer . WriteLine ( attributeString ) ;
203+ }
204+ }
205+ }
206+
87207 writer . Write ( "public " ) ;
88208
89209 if ( element . IsAbstract )
@@ -122,7 +242,16 @@ private static void WriteType(this IndentedTextWriter writer, OpenXmlGeneratorSe
122242 foreach ( var attribute in element . Attributes )
123243 {
124244 delimiter . AddDelimiter ( ) ;
125- writer . WriteAttributeProperty ( services , attribute ) ;
245+
246+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > attrAttributeData )
247+ && attrAttributeData . TryGetValue ( ":" + attribute . Type + "/" + attribute . QName . ToString ( ) , out List < string > attrAttributeStrings ) )
248+ {
249+ writer . WriteAttributeProperty ( services , attribute , attrAttributeStrings ) ;
250+ }
251+ else
252+ {
253+ writer . WriteAttributeProperty ( services , attribute ) ;
254+ }
126255 }
127256
128257 delimiter . AddDelimiter ( ) ;
@@ -132,7 +261,15 @@ private static void WriteType(this IndentedTextWriter writer, OpenXmlGeneratorSe
132261 {
133262 foreach ( var node in element . Children )
134263 {
135- writer . WriteElement ( services , element , node , ref delimiter ) ;
264+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > childAttributeData )
265+ && childAttributeData . TryGetValue ( node . Name , out List < string > childAttributeStrings ) )
266+ {
267+ writer . WriteElement ( services , element , node , ref delimiter , childAttributeStrings ) ;
268+ }
269+ else
270+ {
271+ writer . WriteElement ( services , element , node , ref delimiter ) ;
272+ }
136273 }
137274 }
138275
@@ -318,7 +455,7 @@ void WriteUnion(IndentedTextWriter writer, string name, IEnumerable<Validator> v
318455 }
319456 }
320457
321- private static void WriteElement ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType parent , SchemaElement element , ref Delimiter delimiter )
458+ private static void WriteElement ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType parent , SchemaElement element , ref Delimiter delimiter , List < string > ? attributeStrings = null )
322459 {
323460 if ( string . IsNullOrEmpty ( element . PropertyName ) )
324461 {
@@ -340,6 +477,14 @@ private static void WriteElement(this IndentedTextWriter writer, OpenXmlGenerato
340477 Remarks = $ "xmlns:{ element . Name . QName . Prefix } = { services . GetNamespaceInfo ( element . Name . QName . Prefix ) . Uri } ",
341478 } ) ;
342479
480+ if ( attributeStrings is not null )
481+ {
482+ foreach ( string attributeString in attributeStrings )
483+ {
484+ writer . WriteLine ( attributeString ) ;
485+ }
486+ }
487+
343488 writer . Write ( "public " ) ;
344489 writer . Write ( className ) ;
345490 writer . Write ( "? " ) ;
@@ -377,7 +522,7 @@ internal static void WriteTypedName(this IndentedTextWriter writer, OpenXmlGener
377522 writer . Write ( ")" ) ;
378523 }
379524
380- private static void WriteAttributeProperty ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaAttribute attribute )
525+ private static void WriteAttributeProperty ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaAttribute attribute , List < string > ? attributeStrings = null )
381526 {
382527 var remarks = default ( string ) ;
383528 var info = services . GetNamespaceInfo ( attribute . QName . Prefix ) ;
@@ -401,6 +546,14 @@ private static void WriteAttributeProperty(this IndentedTextWriter writer, OpenX
401546 Remarks = remarks ,
402547 } ) ;
403548
549+ if ( attributeStrings is not null )
550+ {
551+ foreach ( string attributeString in attributeStrings )
552+ {
553+ writer . WriteLine ( attributeString ) ;
554+ }
555+ }
556+
404557 writer . Write ( "public " ) ;
405558 writer . Write ( attribute . Type ) ;
406559 writer . Write ( "? " ) ;
0 commit comments