1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT license.
3
+
4
+ using System . Collections . Generic ;
5
+ using System . Linq ;
6
+ using System . Text . Json . Nodes ;
7
+ using Microsoft . OpenApi . Reader ;
8
+
9
+ namespace Microsoft . OpenApi
10
+ {
11
+ /// <summary>
12
+ /// Schema reference information that includes metadata annotations from JSON Schema 2020-12.
13
+ /// This class extends OpenApiReference to provide schema-specific metadata override capabilities.
14
+ /// </summary>
15
+ public class OpenApiSchemaReferenceInformation : OpenApiReference
16
+ {
17
+ /// <summary>
18
+ /// A default value which by default SHOULD override that of the referenced component.
19
+ /// If the referenced object-type does not allow a default field, then this field has no effect.
20
+ /// </summary>
21
+ public JsonNode ? Default { get ; set ; }
22
+
23
+ /// <summary>
24
+ /// A title which by default SHOULD override that of the referenced component.
25
+ /// If the referenced object-type does not allow a title field, then this field has no effect.
26
+ /// </summary>
27
+ public string ? Title { get ; set ; }
28
+
29
+ /// <summary>
30
+ /// Indicates whether the referenced component is deprecated.
31
+ /// If the referenced object-type does not allow a deprecated field, then this field has no effect.
32
+ /// </summary>
33
+ public bool ? Deprecated { get ; set ; }
34
+
35
+ /// <summary>
36
+ /// Indicates whether the referenced component is read-only.
37
+ /// If the referenced object-type does not allow a readOnly field, then this field has no effect.
38
+ /// </summary>
39
+ public bool ? ReadOnly { get ; set ; }
40
+
41
+ /// <summary>
42
+ /// Indicates whether the referenced component is write-only.
43
+ /// If the referenced object-type does not allow a writeOnly field, then this field has no effect.
44
+ /// </summary>
45
+ public bool ? WriteOnly { get ; set ; }
46
+
47
+ /// <summary>
48
+ /// Example values which by default SHOULD override those of the referenced component.
49
+ /// If the referenced object-type does not allow examples, then this field has no effect.
50
+ /// </summary>
51
+ public IList < JsonNode > ? Examples { get ; set ; }
52
+
53
+ /// <summary>
54
+ /// Parameterless constructor
55
+ /// </summary>
56
+ public OpenApiSchemaReferenceInformation ( ) { }
57
+
58
+ /// <summary>
59
+ /// Initializes a copy instance of the <see cref="OpenApiSchemaReferenceInformation"/> object
60
+ /// </summary>
61
+ public OpenApiSchemaReferenceInformation ( OpenApiSchemaReferenceInformation reference ) : base ( reference )
62
+ {
63
+ Utils . CheckArgumentNull ( reference ) ;
64
+ Default = reference . Default ;
65
+ Title = reference . Title ;
66
+ Deprecated = reference . Deprecated ;
67
+ ReadOnly = reference . ReadOnly ;
68
+ WriteOnly = reference . WriteOnly ;
69
+ Examples = reference . Examples ;
70
+ }
71
+
72
+ /// <summary>
73
+ /// Serialize <see cref="OpenApiSchemaReferenceInformation"/> to Open Api v3.1.
74
+ /// </summary>
75
+ public new void SerializeAsV31 ( IOpenApiWriter writer )
76
+ {
77
+ Utils . CheckArgumentNull ( writer ) ;
78
+
79
+ if ( Type == ReferenceType . Tag && ! string . IsNullOrEmpty ( ReferenceV3 ) && ReferenceV3 is not null )
80
+ {
81
+ // Write the string value only
82
+ writer . WriteValue ( ReferenceV3 ) ;
83
+ return ;
84
+ }
85
+
86
+ writer . WriteStartObject ( ) ;
87
+
88
+ // summary and description are in 3.1 but not in 3.0
89
+ writer . WriteProperty ( OpenApiConstants . Summary , Summary ) ;
90
+ writer . WriteProperty ( OpenApiConstants . Description , Description ) ;
91
+
92
+ // Additional schema metadata annotations in 3.1
93
+ writer . WriteOptionalObject ( OpenApiConstants . Default , Default , ( w , d ) => w . WriteAny ( d ) ) ;
94
+ writer . WriteProperty ( OpenApiConstants . Title , Title ) ;
95
+ if ( Deprecated . HasValue )
96
+ {
97
+ writer . WriteProperty ( OpenApiConstants . Deprecated , Deprecated . Value , false ) ;
98
+ }
99
+ if ( ReadOnly . HasValue )
100
+ {
101
+ writer . WriteProperty ( OpenApiConstants . ReadOnly , ReadOnly . Value , false ) ;
102
+ }
103
+ if ( WriteOnly . HasValue )
104
+ {
105
+ writer . WriteProperty ( OpenApiConstants . WriteOnly , WriteOnly . Value , false ) ;
106
+ }
107
+ if ( Examples != null && Examples . Any ( ) )
108
+ {
109
+ writer . WriteOptionalCollection ( OpenApiConstants . Examples , Examples , ( w , e ) => w . WriteAny ( e ) ) ;
110
+ }
111
+
112
+ // $ref
113
+ writer . WriteProperty ( OpenApiConstants . DollarRef , ReferenceV3 ) ;
114
+
115
+ writer . WriteEndObject ( ) ;
116
+ }
117
+
118
+ /// <summary>
119
+ /// Sets metadata fields from a JSON node during parsing
120
+ /// </summary>
121
+ internal new void SetMetadataFromMapNode ( MapNode mapNode )
122
+ {
123
+ base . SetMetadataFromMapNode ( mapNode ) ;
124
+
125
+ if ( mapNode . JsonNode is not JsonObject jsonObject ) return ;
126
+
127
+ var title = GetPropertyValueFromNode ( jsonObject , OpenApiConstants . Title ) ;
128
+ if ( ! string . IsNullOrEmpty ( title ) )
129
+ {
130
+ Title = title ;
131
+ }
132
+
133
+ // Boolean properties
134
+ if ( jsonObject . TryGetPropertyValue ( OpenApiConstants . Deprecated , out var deprecatedNode ) && deprecatedNode is JsonValue deprecatedValue )
135
+ {
136
+ if ( deprecatedValue . TryGetValue < bool > ( out var deprecated ) )
137
+ {
138
+ Deprecated = deprecated ;
139
+ }
140
+ }
141
+
142
+ if ( jsonObject . TryGetPropertyValue ( OpenApiConstants . ReadOnly , out var readOnlyNode ) && readOnlyNode is JsonValue readOnlyValue )
143
+ {
144
+ if ( readOnlyValue . TryGetValue < bool > ( out var readOnly ) )
145
+ {
146
+ ReadOnly = readOnly ;
147
+ }
148
+ }
149
+
150
+ if ( jsonObject . TryGetPropertyValue ( OpenApiConstants . WriteOnly , out var writeOnlyNode ) && writeOnlyNode is JsonValue writeOnlyValue )
151
+ {
152
+ if ( writeOnlyValue . TryGetValue < bool > ( out var writeOnly ) )
153
+ {
154
+ WriteOnly = writeOnly ;
155
+ }
156
+ }
157
+
158
+ // Default value
159
+ if ( jsonObject . TryGetPropertyValue ( OpenApiConstants . Default , out var defaultNode ) )
160
+ {
161
+ Default = defaultNode ;
162
+ }
163
+
164
+ // Examples
165
+ if ( jsonObject . TryGetPropertyValue ( OpenApiConstants . Examples , out var examplesNode ) && examplesNode is JsonArray examplesArray )
166
+ {
167
+ Examples = new List < JsonNode > ( ) ;
168
+ foreach ( var example in examplesArray )
169
+ {
170
+ if ( example != null )
171
+ {
172
+ Examples . Add ( example ) ;
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ private static string ? GetPropertyValueFromNode ( JsonObject jsonObject , string key ) =>
179
+ jsonObject . TryGetPropertyValue ( key , out var valueNode ) && valueNode is JsonValue valueCast && valueCast . TryGetValue < string > ( out var strValue ) ? strValue : null ;
180
+ }
181
+ }
0 commit comments