diff --git a/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs b/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs
index 3bbae4561..32a828c5b 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using Microsoft.OpenApi.Interfaces;
+using Microsoft.OpenApi.Models.References;
using Microsoft.OpenApi.Writers;
namespace Microsoft.OpenApi.Models
@@ -20,7 +21,7 @@ public class OpenApiDiscriminator : IOpenApiSerializable, IOpenApiExtensible
///
/// An object to hold mappings between payload values and schema names or references.
///
- public IDictionary? Mapping { get; set; } = new Dictionary();
+ public IDictionary? Mapping { get; set; } = new Dictionary();
///
/// This object MAY be extended with Specification Extensions.
@@ -38,7 +39,7 @@ public OpenApiDiscriminator() { }
public OpenApiDiscriminator(OpenApiDiscriminator discriminator)
{
PropertyName = discriminator?.PropertyName ?? PropertyName;
- Mapping = discriminator?.Mapping != null ? new Dictionary(discriminator.Mapping) : null;
+ Mapping = discriminator?.Mapping != null ? new Dictionary(discriminator.Mapping) : null;
Extensions = discriminator?.Extensions != null ? new Dictionary(discriminator.Extensions) : null;
}
@@ -80,7 +81,13 @@ private void SerializeInternal(IOpenApiWriter writer)
writer.WriteProperty(OpenApiConstants.PropertyName, PropertyName);
// mapping
- writer.WriteOptionalMap(OpenApiConstants.Mapping, Mapping, (w, s) => w.WriteValue(s));
+ writer.WriteOptionalMap(OpenApiConstants.Mapping, Mapping, (w, s) =>
+ {
+ if (!string.IsNullOrEmpty(s.Reference.ReferenceV3) && s.Reference.ReferenceV3 is not null)
+ {
+ w.WriteValue(s.Reference.ReferenceV3);
+ }
+ });
}
///
diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs
index 1493283c0..21d8b4171 100644
--- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs
@@ -1,8 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
+using System;
using System.Linq;
using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.References;
using Microsoft.OpenApi.Reader.ParseNodes;
namespace Microsoft.OpenApi.Reader.V3
@@ -22,7 +24,7 @@ internal static partial class OpenApiV3Deserializer
},
{
"mapping",
- (o, n, _) => o.Mapping = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)
+ (o, n, doc) => o.Mapping = n.CreateSimpleMap((node) => LoadMapping(node, doc))
}
};
@@ -40,5 +42,11 @@ public static OpenApiDiscriminator LoadDiscriminator(ParseNode node, OpenApiDocu
return discriminator;
}
+ public static OpenApiSchemaReference LoadMapping(ParseNode node, OpenApiDocument hostDocument)
+ {
+ var pointer = node.GetScalarValue() ?? throw new InvalidOperationException("Could not get a pointer reference");
+ var reference = GetReferenceIdAndExternalResource(pointer);
+ return new OpenApiSchemaReference(reference.Item1, hostDocument, reference.Item2);
+ }
}
}
diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs
index d568b327c..364eb1d54 100644
--- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs
+++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs
@@ -5,11 +5,9 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Exceptions;
-using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
-using Microsoft.OpenApi.Properties;
+using Microsoft.OpenApi.Models.References;
using Microsoft.OpenApi.Reader.ParseNodes;
namespace Microsoft.OpenApi.Reader.V3
@@ -62,7 +60,8 @@ public OpenApiV3VersionService(OpenApiDiagnostic diagnostic)
[typeof(OpenApiServer)] = OpenApiV3Deserializer.LoadServer,
[typeof(OpenApiServerVariable)] = OpenApiV3Deserializer.LoadServerVariable,
[typeof(OpenApiTag)] = OpenApiV3Deserializer.LoadTag,
- [typeof(OpenApiXml)] = OpenApiV3Deserializer.LoadXml
+ [typeof(OpenApiXml)] = OpenApiV3Deserializer.LoadXml,
+ [typeof(OpenApiSchemaReference)] = OpenApiV3Deserializer.LoadMapping
};
public OpenApiDocument LoadDocument(RootNode rootNode)
diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs
index e94f408d2..7eb288fd2 100644
--- a/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs
+++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs
@@ -2,6 +2,7 @@
using System.Linq;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.References;
using Microsoft.OpenApi.Reader.ParseNodes;
namespace Microsoft.OpenApi.Reader.V31
@@ -22,9 +23,9 @@ internal static partial class OpenApiV31Deserializer
}
},
{
- "mapping", (o, n, _) =>
+ "mapping", (o, n, doc) =>
{
- o.Mapping = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!);
+ o.Mapping = n.CreateSimpleMap((node) => LoadMapping(node, doc));
}
}
};
@@ -47,5 +48,12 @@ public static OpenApiDiscriminator LoadDiscriminator(ParseNode node, OpenApiDocu
return discriminator;
}
+
+ public static OpenApiSchemaReference LoadMapping(ParseNode node, OpenApiDocument hostDocument)
+ {
+ var pointer = node.GetScalarValue() ?? throw new InvalidOperationException("Could not get a pointer reference");
+ var reference = GetReferenceIdAndExternalResource(pointer);
+ return new OpenApiSchemaReference(reference.Item1, hostDocument, reference.Item2);
+ }
}
}
diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs
index bb6cac930..3e010be9b 100644
--- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs
+++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs
@@ -5,11 +5,9 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Exceptions;
-using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
-using Microsoft.OpenApi.Properties;
+using Microsoft.OpenApi.Models.References;
using Microsoft.OpenApi.Reader.ParseNodes;
using Microsoft.OpenApi.Reader.V3;
@@ -61,7 +59,8 @@ public OpenApiV31VersionService(OpenApiDiagnostic diagnostic)
[typeof(OpenApiServer)] = OpenApiV31Deserializer.LoadServer,
[typeof(OpenApiServerVariable)] = OpenApiV31Deserializer.LoadServerVariable,
[typeof(OpenApiTag)] = OpenApiV31Deserializer.LoadTag,
- [typeof(OpenApiXml)] = OpenApiV31Deserializer.LoadXml
+ [typeof(OpenApiXml)] = OpenApiV31Deserializer.LoadXml,
+ [typeof(OpenApiSchemaReference)] = OpenApiV31Deserializer.LoadMapping
};
public OpenApiDocument LoadDocument(RootNode rootNode)
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs
index 1629e1939..f1b047f08 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs
@@ -1,9 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
+using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Models.References;
using Microsoft.OpenApi.Reader;
using Xunit;
@@ -25,19 +27,21 @@ public async Task ParseBasicDiscriminatorShouldSucceed()
memoryStream.Position = 0;
// Act
- var discriminator = OpenApiModelFactory.Load(memoryStream, OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Yaml, new(), out var diagnostic, SettingsFixture.ReaderSettings);
+ var openApiDocument = new OpenApiDocument();
+ var discriminator = OpenApiModelFactory.Load(memoryStream, OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Yaml, openApiDocument, out var diagnostic, SettingsFixture.ReaderSettings);
// Assert
Assert.Equivalent(
- new OpenApiDiscriminator
- {
- PropertyName = "pet_type",
- Mapping =
+ new OpenApiDiscriminator
+ {
+ PropertyName = "pet_type",
+ Mapping =
{
- ["puppy"] = "#/components/schemas/Dog",
- ["kitten"] = "Cat"
+ ["puppy"] = new OpenApiSchemaReference("Dog", openApiDocument),
+ ["kitten"] = new OpenApiSchemaReference("Cat" , openApiDocument, "https://gigantic-server.com/schemas/animals.json"),
+ ["monster"] = new OpenApiSchemaReference("schema.json" , openApiDocument, "https://gigantic-server.com/schemas/Monster/schema.json")
}
- }, discriminator);
+ }, discriminator);
}
}
}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDiscriminator/basicDiscriminator.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDiscriminator/basicDiscriminator.yaml
index 7397462f3..21e6adc6c 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDiscriminator/basicDiscriminator.yaml
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDiscriminator/basicDiscriminator.yaml
@@ -1,4 +1,5 @@
propertyName: pet_type
mapping:
puppy: '#/components/schemas/Dog'
- kitten: Cat
\ No newline at end of file
+ kitten: https://gigantic-server.com/schemas/animals.json#/components/schemas/Cat
+ monster: https://gigantic-server.com/schemas/Monster/schema.json
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
index 0d691d05e..755a9e17e 100644
--- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
+++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
@@ -699,7 +699,7 @@ namespace Microsoft.OpenApi.Models
public OpenApiDiscriminator() { }
public OpenApiDiscriminator(Microsoft.OpenApi.Models.OpenApiDiscriminator discriminator) { }
public System.Collections.Generic.IDictionary? Extensions { get; set; }
- public System.Collections.Generic.IDictionary? Mapping { get; set; }
+ public System.Collections.Generic.IDictionary? Mapping { get; set; }
public string? PropertyName { get; set; }
public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { }
public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { }