Skip to content

feat/deep copy - #2990

Draft
Vincent Biret (baywet) wants to merge 3 commits into
mainfrom
feat/deep-copy
Draft

feat/deep copy#2990
Vincent Biret (baywet) wants to merge 3 commits into
mainfrom
feat/deep-copy

Conversation

@baywet

Copy link
Copy Markdown
Member

partial #2967

Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
Copilot AI review requested due to automatic review settings July 23, 2026 17:53
@github-code-quality

Copy link
Copy Markdown

Code Coverage Overview

Languages: C#

C# / code-coverage/dotnet

The overall coverage in commit 27be67d in the feat/deep-copy branch is 87%. The coverage in commit f7680ae in the main branch is 89%.

Show a code coverage summary of the most impacted files.
File main f7680ae feat/deep-copy 27be67d +/-
/home/runner/wo...OpenApiPaths.cs 100% 67% -33%
/home/runner/wo...ApiResponses.cs 100% 67% -33%
/home/runner/wo...ExternalDocs.cs 100% 96% -4%
/home/runner/wo...enApiLicense.cs 100% 97% -3%
/home/runner/wo.../OpenApiInfo.cs 100% 98% -2%
/home/runner/wo...s/OpenApiTag.cs 100% 98% -2%
/home/runner/wo...nApiPathItem.cs 99% 98% -1%
/home/runner/wo...penApiSchema.cs 99% 98% -1%
/home/runner/wo...ApiWorkspace.cs 93% 94% +1%
/home/runner/wo...pCopyContext.cs 0% 43% +43%
};
Add(source, target);
target.Definitions = CopyMap(source.Definitions);
if (source is IOpenApiSchemaMissingProperties missing)
IOpenApiLink link => (T)Copy(link),
IOpenApiCallback callback => (T)Copy(callback),
IOpenApiPathItem pathItem => (T)Copy(pathItem),
OpenApiServer server => (T)(object)Copy(server),
IOpenApiCallback callback => (T)Copy(callback),
IOpenApiPathItem pathItem => (T)Copy(pathItem),
OpenApiServer server => (T)(object)Copy(server),
OpenApiServerVariable serverVariable => (T)(object)Copy(serverVariable),
IOpenApiPathItem pathItem => (T)Copy(pathItem),
OpenApiServer server => (T)(object)Copy(server),
OpenApiServerVariable serverVariable => (T)(object)Copy(serverVariable),
OpenApiSecurityRequirement securityRequirement => (T)(object)Copy(securityRequirement),
OpenApiServer server => (T)(object)Copy(server),
OpenApiServerVariable serverVariable => (T)(object)Copy(serverVariable),
OpenApiSecurityRequirement securityRequirement => (T)(object)Copy(securityRequirement),
OpenApiEncoding encoding => (T)(object)Copy(encoding),
OpenApiServerVariable serverVariable => (T)(object)Copy(serverVariable),
OpenApiSecurityRequirement securityRequirement => (T)(object)Copy(securityRequirement),
OpenApiEncoding encoding => (T)(object)Copy(encoding),
RuntimeExpressionAnyWrapper wrapper => (T)(object)Copy(wrapper),
OpenApiSecurityRequirement securityRequirement => (T)(object)Copy(securityRequirement),
OpenApiEncoding encoding => (T)(object)Copy(encoding),
RuntimeExpressionAnyWrapper wrapper => (T)(object)Copy(wrapper),
OpenApiTag tag => (T)(object)Copy(tag),
OpenApiEncoding encoding => (T)(object)Copy(encoding),
RuntimeExpressionAnyWrapper wrapper => (T)(object)Copy(wrapper),
OpenApiTag tag => (T)(object)Copy(tag),
OpenApiTagReference tagReference => (T)(object)Copy(tagReference),

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an experimental deep-copy API across the OpenAPI.NET object model, providing a way to clone an OpenApiDocument (and many model elements) into an independent object graph while remapping references to the copied host document.

Changes:

  • Adds IDeepCopyable<T> and CreateDeepCopy() implementations across many OpenAPI model and reference-holder types (marked [Experimental("OPENAPI001")]).
  • Introduces OpenApiDeepCopyContext to perform graph-aware cloning (cycle handling + reference remapping via host-document rewriting).
  • Adds unit tests validating deep-copy behavior (graph independence, JsonNode cloning, reference host remap, and ordered tag set preservation).

Reviewed changes

Copilot reviewed 51 out of 51 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/Microsoft.OpenApi.Tests/Models/OpenApiDeepCopyTests.cs Adds tests covering deep-copy behavior (graph independence, JSON node cloning, host-document remap, ordered tags).
src/Microsoft.OpenApi/Services/ReferenceHostDocumentSetter.cs Adds an overwrite mode so deep-copy can force references to point at the copied document.
src/Microsoft.OpenApi/PublicAPI.Unshipped.txt Declares new experimental public surface for IDeepCopyable<T> and CreateDeepCopy() APIs.
src/Microsoft.OpenApi/Models/OpenApiDeepCopyContext.cs New graph-copy engine that clones documents/models, handles cycles, and rewrites reference host documents.
src/Microsoft.OpenApi/Interfaces/IDeepCopyable.cs New experimental interface defining CreateDeepCopy().
src/Microsoft.OpenApi/Attributes/ExperimentalAttribute.cs Adds an internal polyfill for ExperimentalAttribute on pre-.NET8 TFMs.
src/Microsoft.OpenApi/Models/BaseOpenApiReference.cs Adds SetHostDocument to support overwriting host document during deep copy.
src/Microsoft.OpenApi/Microsoft.OpenApi.csproj Suppresses OPENAPI001 in the library build.
src/Microsoft.OpenApi/Models/OpenApiDocument.cs Adds experimental CreateDeepCopy() entry point for documents.
src/Microsoft.OpenApi/Models/OpenApiComponents.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiInfo.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiContact.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiLicense.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiServer.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiServerVariable.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiPaths.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiPathItem.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiOperation.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiResponses.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiResponse.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiParameter.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiMediaType.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiEncoding.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiExample.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiLink.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiCallback.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiOAuthFlow.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiSchema.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiTag.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/OpenApiXml.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/RuntimeExpressionAnyWrapper.cs Adds experimental CreateDeepCopy().
src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs Adds experimental CreateDeepCopy() for schema reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs Adds experimental CreateDeepCopy() for response reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs Adds experimental CreateDeepCopy() for request-body reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs Adds experimental CreateDeepCopy() for parameter reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiMediaTypeReference.cs Adds experimental CreateDeepCopy() for media-type reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs Adds experimental CreateDeepCopy() for header reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs Adds experimental CreateDeepCopy() for example reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs Adds experimental CreateDeepCopy() for link reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs Adds experimental CreateDeepCopy() for callback reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs Adds experimental CreateDeepCopy() for path-item reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs Adds experimental CreateDeepCopy() for security-scheme reference holders.
src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs Adds experimental CreateDeepCopy() for tag reference holders.
.vscode/settings.json Adds “Xunit” to cSpell dictionary.

var target = new OpenApiDocument
{
Workspace = source.Workspace?.BaseUrl != null ? new(source.Workspace.BaseUrl) : source.Workspace != null ? new OpenApiWorkspace() : null,
Comment on lines +893 to +898
private IOpenApiExtension CopyExtension(IOpenApiExtension source) => source switch
{
JsonNodeExtension jsonNodeExtension => new JsonNodeExtension(CopyJsonNode(jsonNodeExtension.Node)),
IDeepCopyable<IOpenApiExtension> deepCopyableExtension => deepCopyableExtension.CreateDeepCopy(),
_ => source
};
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
34.5% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants