Skip to content

Commit 89cd570

Browse files
authored
Include base classes with LINQ generation (#1838)
This change adds support to the LINQ generator to include base classes and their members so it'll be similar to what was in the 2.x version: - Refactor LINQ generator to use a visitor pattern - Add SdtElement expansion - Visit base types Part of #1813
1 parent befa3f4 commit 89cd570

File tree

23 files changed

+1066
-392
lines changed

23 files changed

+1066
-392
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using DocumentFormat.OpenXml.Generator.Models;
5+
6+
namespace DocumentFormat.OpenXml.Generator;
7+
8+
/// <summary>
9+
/// Represents an XName field.
10+
/// </summary>
11+
internal class FieldInfo : IComparable<FieldInfo>, IEquatable<FieldInfo>
12+
{
13+
private const string EmptyNamespace = "NoNamespace";
14+
15+
private readonly OpenXmlGeneratorServices _services;
16+
17+
private readonly HashSet<SchemaType> _elementMetadata = new();
18+
private readonly HashSet<SchemaType> _parentMetadata = new();
19+
private readonly HashSet<SchemaType> _childMetadata = new();
20+
21+
private readonly HashSet<SchemaType> _attributeContainerMetadata = new();
22+
private readonly HashSet<SchemaAttribute> _attributeMetadata = new();
23+
24+
private readonly SortedSet<string> _attributePropertyNames = new();
25+
26+
/// <summary>
27+
/// Initializes a new instance with the given <see cref="QName" />.
28+
/// </summary>
29+
/// <param name="qName">The <see cref="QName" />.</param>
30+
public FieldInfo(QName qName, OpenXmlGeneratorServices services)
31+
{
32+
QName = qName;
33+
FieldName = qName.Name;
34+
_services = services;
35+
}
36+
37+
/// <summary>
38+
/// Gets the <see cref="QName" />.
39+
/// </summary>
40+
public QName QName { get; }
41+
42+
/// <summary>
43+
/// Gets or sets the field name, e.g., "document".
44+
/// </summary>
45+
public string FieldName { get; set; }
46+
47+
/// <summary>
48+
/// Gets the qualified field name, e.g., "W.document".
49+
/// </summary>
50+
public string QualifiedFieldName =>
51+
Prefix != string.Empty
52+
? Prefix.ToUpperInvariant() + "." + FieldName
53+
: EmptyNamespace + "." + FieldName;
54+
55+
/// <summary>
56+
/// Gets the XML prefix, e.g., "w".
57+
/// </summary>
58+
public string Prefix => QName.Prefix;
59+
60+
/// <summary>
61+
/// Gets the XML namespace name, e.g., "http://schemas.openxmlformats.org/wordprocessingml/2006/main".
62+
/// </summary>
63+
public string NamespaceName => _services.GetNamespaceInfo(QName.Prefix).Uri;
64+
65+
/// <summary>
66+
/// Gets the XML local name, e.g., "document".
67+
/// </summary>
68+
public string LocalName => QName.Name;
69+
70+
/// <summary>
71+
/// Gets the XML qualified name, e.g., "w:document".
72+
/// </summary>
73+
public string QualifiedName => string.IsNullOrEmpty(Prefix) ? LocalName : Prefix + ":" + LocalName;
74+
75+
public IEnumerable<QName> ParentQualifiedNames =>
76+
_parentMetadata
77+
.OrderBy(GetQualifiedName)
78+
.Select(em => em.Name.QName)
79+
.Distinct();
80+
81+
public IEnumerable<QName> ChildQualifiedNames =>
82+
_childMetadata
83+
.OrderBy(GetQualifiedName)
84+
.Select(em => em.Name.QName)
85+
.Distinct();
86+
87+
public IEnumerable<QName> AttributeContainerQualifiedNames =>
88+
_attributeContainerMetadata
89+
.OrderBy(GetQualifiedName)
90+
.Select(em => em.Name.QName)
91+
.Distinct();
92+
93+
public IEnumerable<QName> ElementAttributeQualifiedNames =>
94+
_elementMetadata
95+
.SelectMany(em => em.Attributes)
96+
.OrderBy(GetQualifiedName)
97+
.Select(am => am.QName)
98+
.Distinct();
99+
100+
public IEnumerable<string> ElementClassNames =>
101+
_elementMetadata
102+
.Select(e => _services.FindClassName(e.Name, fullyQualified: false))
103+
.Distinct()
104+
.OrderBy(name => name);
105+
106+
public IEnumerable<string> AttributePropertyNames => _attributePropertyNames;
107+
108+
private static string GetQualifiedName(SchemaType metadata)
109+
{
110+
return GetQualifiedName(metadata.Name.QName);
111+
}
112+
113+
private static string GetQualifiedName(SchemaAttribute metadata)
114+
{
115+
return GetQualifiedName(metadata.QName);
116+
}
117+
118+
private static string GetQualifiedName(QName qName)
119+
=> qName.ToString();
120+
121+
public void AddElementMetadata(SchemaType element)
122+
{
123+
_elementMetadata.Add(element);
124+
}
125+
126+
public void AddParentElementMetadata(SchemaType? parent)
127+
{
128+
if (parent is not null)
129+
{
130+
_parentMetadata.Add(parent);
131+
}
132+
}
133+
134+
public void AddChildElementMetadata(SchemaType child)
135+
{
136+
_childMetadata.Add(child);
137+
}
138+
139+
public void AddAttributeMetadata(SchemaType element, SchemaAttribute attribute)
140+
{
141+
_attributeContainerMetadata.Add(element);
142+
_attributeMetadata.Add(attribute);
143+
144+
var className = _services.FindClassName(element.Name, fullyQualified: false);
145+
_attributePropertyNames.Add(className + "." + attribute.PropertyName);
146+
}
147+
148+
/// <inheritdoc />
149+
public int CompareTo(FieldInfo? other)
150+
{
151+
return other is null ? 1 : QName.CompareTo(other.QName);
152+
}
153+
154+
/// <inheritdoc />
155+
public bool Equals(FieldInfo? other)
156+
=> other is not null && QName.Equals(other.QName);
157+
158+
/// <inheritdoc />
159+
public override bool Equals(object? obj)
160+
{
161+
if (obj is null)
162+
{
163+
return false;
164+
}
165+
166+
if (ReferenceEquals(this, obj))
167+
{
168+
return true;
169+
}
170+
171+
return obj.GetType() == GetType() && Equals((FieldInfo)obj);
172+
}
173+
174+
/// <inheritdoc />
175+
public override int GetHashCode()
176+
{
177+
return QName.GetHashCode();
178+
}
179+
180+
public static bool operator ==(FieldInfo? left, FieldInfo? right)
181+
{
182+
return Equals(left, right);
183+
}
184+
185+
public static bool operator !=(FieldInfo? left, FieldInfo? right)
186+
{
187+
return !Equals(left, right);
188+
}
189+
}

0 commit comments

Comments
 (0)