Skip to content

Commit 902936e

Browse files
committed
Add a v31 schema deserializer
1 parent a59ba31 commit 902936e

File tree

1 file changed

+238
-0
lines changed

1 file changed

+238
-0
lines changed
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using Microsoft.OpenApi.Extensions;
5+
using Microsoft.OpenApi.Models;
6+
using Microsoft.OpenApi.Reader.ParseNodes;
7+
using System.Collections.Generic;
8+
using System.Globalization;
9+
10+
namespace Microsoft.OpenApi.Reader.V31
11+
{
12+
internal static partial class OpenApiV31Deserializer
13+
{
14+
private static readonly FixedFieldMap<OpenApiSchema> _openApiSchemaFixedFields = new()
15+
{
16+
{
17+
"title",
18+
(o, n, _) => o.Title = n.GetScalarValue()
19+
},
20+
{
21+
"$schema",
22+
(o, n, _) => o.Schema = n.GetScalarValue()
23+
},
24+
{
25+
"$id",
26+
(o, n, _) => o.Id = n.GetScalarValue()
27+
},
28+
{
29+
"$comment",
30+
(o, n, _) => o.Comment = n.GetScalarValue()
31+
},
32+
{
33+
"$vocabulary",
34+
(o, n, _) => o.Vocabulary = n.GetScalarValue()
35+
},
36+
{
37+
"$dynamicRef",
38+
(o, n, _) => o.DynamicRef = n.GetScalarValue()
39+
},
40+
{
41+
"$dynamicAnchor",
42+
(o, n, _) => o.DynamicAnchor = n.GetScalarValue()
43+
},
44+
{
45+
"$recursiveAnchor",
46+
(o, n, _) => o.RecursiveAnchor = n.GetScalarValue()
47+
},
48+
{
49+
"$recursiveRef",
50+
(o, n, _) => o.RecursiveRef = n.GetScalarValue()
51+
},
52+
{
53+
"$defs",
54+
(o, n, t) => o.Definitions = n.CreateMap(LoadOpenApiSchema, t)
55+
},
56+
{
57+
"multipleOf",
58+
(o, n, _) => o.MultipleOf = decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture)
59+
},
60+
{
61+
"maximum",
62+
(o, n, _) => o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue)
63+
},
64+
{
65+
"exclusiveMaximum",
66+
(o, n, _) => o.V31ExclusiveMaximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue)
67+
},
68+
{
69+
"minimum",
70+
(o, n, _) => o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MinValue)
71+
},
72+
{
73+
"exclusiveMinimum",
74+
(o, n, _) => o.V31ExclusiveMinimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue)
75+
},
76+
{
77+
"maxLength",
78+
(o, n, _) => o.MaxLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
79+
},
80+
{
81+
"minLength",
82+
(o, n, _) => o.MinLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
83+
},
84+
{
85+
"pattern",
86+
(o, n, _) => o.Pattern = n.GetScalarValue()
87+
},
88+
{
89+
"maxItems",
90+
(o, n, _) => o.MaxItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
91+
},
92+
{
93+
"minItems",
94+
(o, n, _) => o.MinItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
95+
},
96+
{
97+
"uniqueItems",
98+
(o, n, _) => o.UniqueItems = bool.Parse(n.GetScalarValue())
99+
},
100+
{
101+
"unevaluatedProperties",
102+
(o, n, _) => o.UnevaluatedProperties = bool.Parse(n.GetScalarValue())
103+
},
104+
{
105+
"maxProperties",
106+
(o, n, _) => o.MaxProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
107+
},
108+
{
109+
"minProperties",
110+
(o, n, _) => o.MinProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
111+
},
112+
{
113+
"required",
114+
(o, n, _) => o.Required = new HashSet<string>(n.CreateSimpleList((n2, p) => n2.GetScalarValue()))
115+
},
116+
{
117+
"enum",
118+
(o, n, _) => o.Enum = n.CreateListOfAny()
119+
},
120+
{
121+
"type",
122+
(o, n, _) => o.TypeArray = n.CreateSimpleList((n2, p) => n2.GetScalarValue()).ToArray()
123+
124+
},
125+
{
126+
"allOf",
127+
(o, n, t) => o.AllOf = n.CreateList(LoadOpenApiSchema, t)
128+
},
129+
{
130+
"oneOf",
131+
(o, n, t) => o.OneOf = n.CreateList(LoadOpenApiSchema, t)
132+
},
133+
{
134+
"anyOf",
135+
(o, n, t) => o.AnyOf = n.CreateList(LoadOpenApiSchema, t)
136+
},
137+
{
138+
"not",
139+
(o, n, _) => o.Not = LoadOpenApiSchema(n)
140+
},
141+
{
142+
"items",
143+
(o, n, _) => o.Items = LoadOpenApiSchema(n)
144+
},
145+
{
146+
"properties",
147+
(o, n, t) => o.Properties = n.CreateMap(LoadOpenApiSchema, t)
148+
},
149+
{
150+
"additionalProperties", (o, n, _) =>
151+
{
152+
if (n is ValueNode)
153+
{
154+
o.AdditionalPropertiesAllowed = bool.Parse(n.GetScalarValue());
155+
}
156+
else
157+
{
158+
o.AdditionalProperties = LoadOpenApiSchema(n);
159+
}
160+
}
161+
},
162+
{
163+
"description",
164+
(o, n, _) => o.Description = n.GetScalarValue()
165+
},
166+
{
167+
"format",
168+
(o, n, _) => o.Format = n.GetScalarValue()
169+
},
170+
{
171+
"default",
172+
(o, n, _) => o.Default = n.CreateAny()
173+
},
174+
{
175+
"nullable",
176+
(o, n, _) => o.Nullable = bool.Parse(n.GetScalarValue())
177+
},
178+
{
179+
"discriminator",
180+
(o, n, _) => o.Discriminator = LoadDiscriminator(n)
181+
},
182+
{
183+
"readOnly",
184+
(o, n, _) => o.ReadOnly = bool.Parse(n.GetScalarValue())
185+
},
186+
{
187+
"writeOnly",
188+
(o, n, _) => o.WriteOnly = bool.Parse(n.GetScalarValue())
189+
},
190+
{
191+
"xml",
192+
(o, n, _) => o.Xml = LoadXml(n)
193+
},
194+
{
195+
"externalDocs",
196+
(o, n, _) => o.ExternalDocs = LoadExternalDocs(n)
197+
},
198+
{
199+
"example",
200+
(o, n, _) => o.Example = n.CreateAny()
201+
},
202+
{
203+
"deprecated",
204+
(o, n, _) => o.Deprecated = bool.Parse(n.GetScalarValue())
205+
},
206+
};
207+
208+
private static readonly PatternFieldMap<OpenApiSchema> _openApiSchemaPatternFields = new()
209+
{
210+
{s => s.StartsWith("x-"), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}
211+
};
212+
213+
public static OpenApiSchema LoadOpenApiSchema(ParseNode node, OpenApiDocument hostDocument = null)
214+
{
215+
var mapNode = node.CheckMapNode(OpenApiConstants.Schema);
216+
217+
var pointer = mapNode.GetReferencePointer();
218+
219+
if (pointer != null)
220+
{
221+
return new()
222+
{
223+
UnresolvedReference = true,
224+
Reference = node.Context.VersionService.ConvertToOpenApiReference(pointer, ReferenceType.Schema)
225+
};
226+
}
227+
228+
var schema = new OpenApiSchema();
229+
230+
foreach (var propertyNode in mapNode)
231+
{
232+
propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields);
233+
}
234+
235+
return schema;
236+
}
237+
}
238+
}

0 commit comments

Comments
 (0)