Skip to content

Commit 086fc56

Browse files
committed
Create a proxy object for resolving referenced schemas
1 parent 396d450 commit 086fc56

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using Microsoft.OpenApi.Any;
5+
using Microsoft.OpenApi.Interfaces;
6+
using Microsoft.OpenApi.Writers;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Text.Json.Nodes;
10+
11+
namespace Microsoft.OpenApi.Models.References
12+
{
13+
/// <summary>
14+
/// Schema reference object
15+
/// </summary>
16+
public class OpenApiSchemaReference : OpenApiSchema
17+
{
18+
internal OpenApiSchema _target;
19+
private readonly OpenApiReference _reference;
20+
private string _description;
21+
22+
private OpenApiSchema Target
23+
{
24+
get
25+
{
26+
_target ??= Reference.HostDocument.ResolveReferenceTo<OpenApiSchema>(_reference);
27+
OpenApiSchema resolved = new OpenApiSchema(_target);
28+
if (!string.IsNullOrEmpty(_description)) resolved.Description = _description;
29+
return resolved;
30+
}
31+
}
32+
33+
/// <summary>
34+
/// Constructor initializing the reference object.
35+
/// </summary>
36+
/// <param name="referenceId">The reference Id.</param>
37+
/// <param name="hostDocument">The host OpenAPI document.</param>
38+
/// <param name="externalResource">Optional: External resource in the reference.
39+
/// It may be:
40+
/// 1. a absolute/relative file path, for example: ../commons/pet.json
41+
/// 2. a Url, for example: http://localhost/pet.json
42+
/// </param>
43+
public OpenApiSchemaReference(string referenceId, OpenApiDocument hostDocument, string externalResource = null)
44+
{
45+
if (string.IsNullOrEmpty(referenceId))
46+
{
47+
Utils.CheckArgumentNullOrEmpty(referenceId);
48+
}
49+
50+
_reference = new OpenApiReference()
51+
{
52+
Id = referenceId,
53+
HostDocument = hostDocument,
54+
Type = ReferenceType.Schema,
55+
ExternalResource = externalResource
56+
};
57+
58+
Reference = _reference;
59+
}
60+
61+
internal OpenApiSchemaReference(OpenApiSchema target, string referenceId)
62+
{
63+
_target = target;
64+
65+
_reference = new OpenApiReference()
66+
{
67+
Id = referenceId,
68+
Type = ReferenceType.Schema,
69+
};
70+
}
71+
72+
/// <inheritdoc/>
73+
public override string Title { get => Target.Title; set => Target.Title = value; }
74+
/// <inheritdoc/>
75+
public override string Schema { get => Target.Schema; set => Target.Schema = value; }
76+
/// <inheritdoc/>
77+
public override string Id { get => Target.Id; set => Target.Id = value; }
78+
/// <inheritdoc/>
79+
public override string Comment { get => Target.Comment; set => Target.Comment = value; }
80+
/// <inheritdoc/>
81+
public override string Vocabulary { get => Target.Vocabulary; set => Target.Vocabulary = value; }
82+
/// <inheritdoc/>
83+
public override string DynamicRef { get => Target.DynamicRef; set => Target.DynamicRef = value; }
84+
/// <inheritdoc/>
85+
public override string DynamicAnchor { get => Target.DynamicAnchor; set => Target.DynamicAnchor = value; }
86+
/// <inheritdoc/>
87+
public override string RecursiveAnchor { get => Target.RecursiveAnchor; set => Target.RecursiveAnchor = value; }
88+
/// <inheritdoc/>
89+
public override string RecursiveRef { get => Target.RecursiveRef; set => Target.RecursiveRef = value; }
90+
/// <inheritdoc/>
91+
public override IDictionary<string, OpenApiSchema> Definitions { get => Target.Definitions; set => Target.Definitions = value; }
92+
/// <inheritdoc/>
93+
public override decimal? V31ExclusiveMaximum { get => Target.V31ExclusiveMaximum; set => Target.V31ExclusiveMaximum = value; }
94+
/// <inheritdoc/>
95+
public override decimal? V31ExclusiveMinimum { get => Target.V31ExclusiveMinimum; set => Target.V31ExclusiveMinimum = value; }
96+
/// <inheritdoc/>
97+
public override bool UnEvaluatedProperties { get => Target.UnEvaluatedProperties; set => Target.UnEvaluatedProperties = value; }
98+
/// <inheritdoc/>
99+
public override object Type { get => Target.Type; set => Target.Type = value; }
100+
/// <inheritdoc/>
101+
public override string Format { get => Target.Format; set => Target.Format = value; }
102+
/// <inheritdoc/>
103+
public override string Description { get => Target.Description; set => Target.Description = value; }
104+
/// <inheritdoc/>
105+
public override decimal? Maximum { get => Target.Maximum; set => Target.Maximum = value; }
106+
/// <inheritdoc/>
107+
public override bool? ExclusiveMaximum { get => Target.ExclusiveMaximum; set => Target.ExclusiveMaximum = value; }
108+
/// <inheritdoc/>
109+
public override decimal? Minimum { get => Target.Minimum; set => Target.Minimum = value; }
110+
/// <inheritdoc/>
111+
public override bool? ExclusiveMinimum { get => Target.ExclusiveMinimum; set => Target.ExclusiveMinimum = value; }
112+
/// <inheritdoc/>
113+
public override int? MaxLength { get => Target.MaxLength; set => Target.MaxLength = value; }
114+
/// <inheritdoc/>
115+
public override int? MinLength { get => Target.MinLength; set => Target.MinLength = value; }
116+
/// <inheritdoc/>
117+
public override string Pattern { get => Target.Pattern; set => Target.Pattern = value; }
118+
/// <inheritdoc/>
119+
public override decimal? MultipleOf { get => Target.MultipleOf; set => Target.MultipleOf = value; }
120+
/// <inheritdoc/>
121+
public override OpenApiAny Default { get => Target.Default; set => Target.Default = value; }
122+
/// <inheritdoc/>
123+
public override bool ReadOnly { get => Target.ReadOnly; set => Target.ReadOnly = value; }
124+
/// <inheritdoc/>
125+
public override bool WriteOnly { get => Target.WriteOnly; set => Target.WriteOnly = value; }
126+
/// <inheritdoc/>
127+
public override IList<OpenApiSchema> AllOf { get => Target.AllOf; set => Target.AllOf = value; }
128+
/// <inheritdoc/>
129+
public override IList<OpenApiSchema> OneOf { get => Target.OneOf; set => Target.OneOf = value; }
130+
/// <inheritdoc/>
131+
public override IList<OpenApiSchema> AnyOf { get => Target.AnyOf; set => Target.AnyOf = value; }
132+
/// <inheritdoc/>
133+
public override OpenApiSchema Not { get => Target.Not; set => Target.Not = value; }
134+
/// <inheritdoc/>
135+
public override ISet<string> Required { get => Target.Required; set => Target.Required = value; }
136+
/// <inheritdoc/>
137+
public override OpenApiSchema Items { get => Target.Items; set => Target.Items = value; }
138+
/// <inheritdoc/>
139+
public override int? MaxItems { get => Target.MaxItems; set => Target.MaxItems = value; }
140+
/// <inheritdoc/>
141+
public override int? MinItems { get => Target.MinItems; set => Target.MinItems = value; }
142+
/// <inheritdoc/>
143+
public override bool? UniqueItems { get => Target.UniqueItems; set => Target.UniqueItems = value; }
144+
/// <inheritdoc/>
145+
public override IDictionary<string, OpenApiSchema> Properties { get => Target.Properties; set => Target.Properties = value; }
146+
/// <inheritdoc/>
147+
public override IDictionary<string, OpenApiSchema> PatternProperties { get => Target.PatternProperties; set => Target.PatternProperties = value; }
148+
/// <inheritdoc/>
149+
public override int? MaxProperties { get => Target.MaxProperties; set => Target.MaxProperties = value; }
150+
/// <inheritdoc/>
151+
public override int? MinProperties { get => Target.MinProperties; set => Target.MinProperties = value; }
152+
/// <inheritdoc/>
153+
public override bool AdditionalPropertiesAllowed { get => Target.AdditionalPropertiesAllowed; set => Target.AdditionalPropertiesAllowed = value; }
154+
/// <inheritdoc/>
155+
public override OpenApiSchema AdditionalProperties { get => Target.AdditionalProperties; set => Target.AdditionalProperties = value; }
156+
/// <inheritdoc/>
157+
public override OpenApiDiscriminator Discriminator { get => Target.Discriminator; set => Target.Discriminator = value; }
158+
/// <inheritdoc/>
159+
public override OpenApiAny Example { get => Target.Example; set => Target.Example = value; }
160+
/// <inheritdoc/>
161+
public override IList<JsonNode> Examples { get => Target.Examples; set => Target.Examples = value; }
162+
/// <inheritdoc/>
163+
public override IList<JsonNode> Enum { get => Target.Enum; set => Target.Enum = value; }
164+
/// <inheritdoc/>
165+
public override bool Nullable { get => Target.Nullable; set => Target.Nullable = value; }
166+
/// <inheritdoc/>
167+
public override bool UnevaluatedProperties { get => Target.UnevaluatedProperties; set => Target.UnevaluatedProperties = value; }
168+
/// <inheritdoc/>
169+
public override OpenApiExternalDocs ExternalDocs { get => Target.ExternalDocs; set => Target.ExternalDocs = value; }
170+
/// <inheritdoc/>
171+
public override bool Deprecated { get => Target.Deprecated; set => Target.Deprecated = value; }
172+
/// <inheritdoc/>
173+
public override OpenApiXml Xml { get => Target.Xml; set => Target.Xml = value; }
174+
/// <inheritdoc/>
175+
public override IDictionary<string, IOpenApiExtension> Extensions { get => Target.Extensions; set => Target.Extensions = value; }
176+
177+
/// <inheritdoc/>
178+
public override void SerializeAsV31(IOpenApiWriter writer)
179+
{
180+
if (!writer.GetSettings().ShouldInlineReference(_reference))
181+
{
182+
_reference.SerializeAsV31(writer);
183+
return;
184+
}
185+
else
186+
{
187+
SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer));
188+
}
189+
}
190+
191+
/// <inheritdoc/>
192+
public override void SerializeAsV3(IOpenApiWriter writer)
193+
{
194+
if (!writer.GetSettings().ShouldInlineReference(_reference))
195+
{
196+
_reference.SerializeAsV3(writer);
197+
return;
198+
}
199+
else
200+
{
201+
SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer));
202+
}
203+
}
204+
205+
/// <inheritdoc/>
206+
public override void SerializeAsV2(IOpenApiWriter writer)
207+
{
208+
if (!writer.GetSettings().ShouldInlineReference(_reference))
209+
{
210+
_reference.SerializeAsV2(writer);
211+
return;
212+
}
213+
else
214+
{
215+
SerializeInternal(writer, (writer, element) => element.SerializeAsV2WithoutReference(writer));
216+
}
217+
}
218+
219+
/// <inheritdoc/>
220+
private void SerializeInternal(IOpenApiWriter writer,
221+
Action<IOpenApiWriter, IOpenApiReferenceable> action)
222+
{
223+
Utils.CheckArgumentNull(writer);
224+
action(writer, Target);
225+
}
226+
}
227+
}

0 commit comments

Comments
 (0)