Skip to content

Commit 3000226

Browse files
committed
Add V2 schema deserializer
1 parent 71215ac commit 3000226

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using System.Globalization;
6+
using Microsoft.OpenApi.Interfaces;
7+
using Microsoft.OpenApi.Models;
8+
using Microsoft.OpenApi.Extensions;
9+
using Microsoft.OpenApi.Reader.ParseNodes;
10+
using Microsoft.OpenApi.Readers.ParseNodes;
11+
12+
namespace Microsoft.OpenApi.Reader.V2
13+
{
14+
/// <summary>
15+
/// Class containing logic to deserialize Open API V2 document into
16+
/// runtime Open API object model.
17+
/// </summary>
18+
internal static partial class OpenApiV2Deserializer
19+
{
20+
private static readonly FixedFieldMap<OpenApiSchema> _schemaFixedFields = new()
21+
{
22+
{
23+
"title",
24+
(o, n) => o.Title = n.GetScalarValue()
25+
},
26+
{
27+
"multipleOf",
28+
(o, n) => o.MultipleOf = decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture)
29+
},
30+
{
31+
"maximum",
32+
(o, n) => o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue)
33+
},
34+
{
35+
"exclusiveMaximum",
36+
(o, n) => o.ExclusiveMaximum = bool.Parse(n.GetScalarValue())
37+
},
38+
{
39+
"minimum",
40+
(o, n) => o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MinValue)
41+
},
42+
{
43+
"exclusiveMinimum",
44+
(o, n) => o.ExclusiveMinimum = bool.Parse(n.GetScalarValue())
45+
},
46+
{
47+
"maxLength",
48+
(o, n) => o.MaxLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
49+
},
50+
{
51+
"minLength",
52+
(o, n) => o.MinLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
53+
},
54+
{
55+
"pattern",
56+
(o, n) => o.Pattern = n.GetScalarValue()
57+
},
58+
{
59+
"maxItems",
60+
(o, n) => o.MaxItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
61+
},
62+
{
63+
"minItems",
64+
(o, n) => o.MinItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
65+
},
66+
{
67+
"uniqueItems",
68+
(o, n) => o.UniqueItems = bool.Parse(n.GetScalarValue())
69+
},
70+
{
71+
"maxProperties",
72+
(o, n) => o.MaxProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
73+
},
74+
{
75+
"minProperties",
76+
(o, n) => o.MinProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture)
77+
},
78+
{
79+
"required",
80+
(o, n) => o.Required = new HashSet<string>(n.CreateSimpleList(n2 => n2.GetScalarValue()))
81+
},
82+
{
83+
"enum",
84+
(o, n) => o.Enum = n.CreateListOfAny()
85+
},
86+
87+
{
88+
"type",
89+
(o, n) => o.Type = n.GetScalarValue()
90+
},
91+
{
92+
"allOf",
93+
(o, n) => o.AllOf = n.CreateList(LoadSchema)
94+
},
95+
{
96+
"items",
97+
(o, n) => o.Items = LoadSchema(n)
98+
},
99+
{
100+
"properties",
101+
(o, n) => o.Properties = n.CreateMap(LoadSchema)
102+
},
103+
{
104+
"additionalProperties", (o, n) =>
105+
{
106+
if (n is ValueNode)
107+
{
108+
o.AdditionalPropertiesAllowed = bool.Parse(n.GetScalarValue());
109+
}
110+
else
111+
{
112+
o.AdditionalProperties = LoadSchema(n);
113+
}
114+
}
115+
},
116+
{
117+
"description",
118+
(o, n) => o.Description = n.GetScalarValue()
119+
},
120+
{
121+
"format",
122+
(o, n) => o.Format = n.GetScalarValue()
123+
},
124+
{
125+
"default",
126+
(o, n) => o.Default = n.CreateAny()
127+
},
128+
{
129+
"discriminator", (o, n) =>
130+
{
131+
o.Discriminator = new()
132+
{
133+
PropertyName = n.GetScalarValue()
134+
};
135+
}
136+
},
137+
{
138+
"readOnly",
139+
(o, n) => o.ReadOnly = bool.Parse(n.GetScalarValue())
140+
},
141+
{
142+
"xml",
143+
(o, n) => o.Xml = LoadXml(n)
144+
},
145+
{
146+
"externalDocs",
147+
(o, n) => o.ExternalDocs = LoadExternalDocs(n)
148+
},
149+
{
150+
"example",
151+
(o, n) => o.Example = n.CreateAny()
152+
},
153+
};
154+
155+
private static readonly PatternFieldMap<OpenApiSchema> _schemaPatternFields = new PatternFieldMap<OpenApiSchema>
156+
{
157+
{s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))}
158+
};
159+
160+
public static OpenApiSchema LoadSchema(ParseNode node)
161+
{
162+
var mapNode = node.CheckMapNode("schema");
163+
164+
var pointer = mapNode.GetReferencePointer();
165+
if (pointer != null)
166+
{
167+
return mapNode.GetReferencedObject<OpenApiSchema>(ReferenceType.Schema, pointer);
168+
}
169+
170+
var schema = new OpenApiSchema();
171+
172+
foreach (var propertyNode in mapNode)
173+
{
174+
propertyNode.ParseField(schema, _schemaFixedFields, _schemaPatternFields);
175+
}
176+
177+
return schema;
178+
}
179+
180+
private static Dictionary<string, IOpenApiExtension> LoadExtensions(string value, IOpenApiExtension extension)
181+
{
182+
var extensions = new Dictionary<string, IOpenApiExtension>
183+
{
184+
{ value, extension }
185+
};
186+
return extensions;
187+
}
188+
}
189+
}

0 commit comments

Comments
 (0)