Skip to content

Add example allOf with single ref #10948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.Sets;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.servers.Server;
Expand All @@ -24,6 +25,8 @@
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.openapitools.codegen.utils.StringUtils.*;

Expand Down Expand Up @@ -510,7 +513,7 @@ public ModelsMap postProcessModels(ModelsMap objs) {
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
if (!model.isEnum && property.isEnum) {
if (!model.isEnum && property.isEnum && property.getComposedSchemas() == null) {
// These are inner enums, enums which do not exist as models, just as properties.
// They are handled via the enum_inline template and are generated in the
// same file as the containing class. To prevent name clashes the inline enum classes
Expand All @@ -532,6 +535,37 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
}
}

@Override
public CodegenProperty fromProperty(String name, Schema p) {
final CodegenProperty property = super.fromProperty(name, p);

// Handle composed properties
if (ModelUtils.isComposedSchema(p)) {
ComposedSchema composed = (ComposedSchema) p;

// Count the occurrences of allOf/anyOf/oneOf with exactly one child element
long count = Stream.of(composed.getAllOf(), composed.getAnyOf(), composed.getOneOf())
Copy link
Member

Choose a reason for hiding this comment

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

@kuhnroyal thanks again for the PR. I now recall there's similar change before to another generator do something very similar but some users do not like it.

Let me know when you're free in the coming week and we can discuss further via Slack.

.filter(list -> list != null && list.size() == 1).count();

if (count == 1) {
// Continue only if there is one element that matches
// and basically treat it as simple property.
Stream.of(composed.getAllOf(), composed.getAnyOf(), composed.getOneOf())
.filter(list -> list != null && list.size() == 1)
.findFirst()
.map(list -> list.get(0).get$ref())
.map(ModelUtils::getSimpleRef)
.map(ref -> ModelUtils.getSchemas(this.openAPI).get(ref))
.ifPresent(schema -> {
property.isEnum = schema.getEnum() != null;
property.isModel = true;
});

}
}
return property;
}

@Override
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List<Server> servers) {
final CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers);
Expand Down Expand Up @@ -616,13 +650,6 @@ private List<Map<String, String>> prioritizeContentTypes(List<Map<String, String
return prioritizedContentTypes;
}

private static boolean isMultipartType(String mediaType) {
if (mediaType != null) {
return "multipart/form-data".equals(mediaType);
}
return false;
}

@Override
protected void updateEnumVarsWithExtensions(List<Map<String, Object>> enumVars, Map<String, Object> vendorExtensions, String dataType) {
if (vendorExtensions != null && useEnumExtension && vendorExtensions.containsKey("x-enum-values")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
property.isNullable = true;
}

if (property.isEnum) {
if (property.isEnum && property.getComposedSchemas() == null) {
// enums are generated with built_value and make use of BuiltSet
model.imports.add("BuiltSet");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ public ModelsMap postProcessModels(ModelsMap objs) {
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
if (SERIALIZATION_LIBRARY_BUILT_VALUE.equals(library)) {
if (property.isEnum) {
if (property.isEnum && property.getComposedSchemas() == null) {
// enums are generated with built_value and make use of BuiltSet
model.imports.add("BuiltSet");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,28 @@ class _${{classname}}Serializer implements StructuredSerializer<{{classname}}> {
result.{{{name}}}.replace(serializers.deserialize(value,
specifiedType: {{{vendorExtensions.x-built-value-serializer-type}}}) as {{{datatypeWithEnum}}});
{{/isContainer}}
{{^isContainer}}
{{#isEnum}}
result.{{{name}}} = serializers.deserialize(value,
specifiedType: {{{vendorExtensions.x-built-value-serializer-type}}}) as {{{datatypeWithEnum}}};
{{/isEnum}}
{{^isEnum}}
{{#isModel}}
{{#isPrimitiveType}}
{{! These are models that have been manually marked as primitive via generator param. }} result.{{{name}}} = valueDes;
result.{{{name}}} = serializers.deserialize(value,
specifiedType: {{{vendorExtensions.x-built-value-serializer-type}}}) as {{{datatypeWithEnum}}};
{{/isPrimitiveType}}
{{^isPrimitiveType}}
result.{{{name}}}.replace(serializers.deserialize(value,
specifiedType: {{{vendorExtensions.x-built-value-serializer-type}}}) as {{{datatypeWithEnum}}});
{{/isPrimitiveType}}
{{/isModel}}
{{^isContainer}}
{{^isModel}}
result.{{{name}}} = serializers.deserialize(value,
specifiedType: {{{vendorExtensions.x-built-value-serializer-type}}}) as {{{datatypeWithEnum}}};
{{/isModel}}
{{/isEnum}}
{{/isContainer}}
break;
{{/vars}}
Expand All @@ -121,6 +134,7 @@ class _${{classname}}Serializer implements StructuredSerializer<{{classname}}> {
enum.mustache template.
}}
{{#vars}}
{{^isModel}}
{{#isEnum}}
{{^isContainer}}

Expand All @@ -133,4 +147,5 @@ class _${{classname}}Serializer implements StructuredSerializer<{{classname}}> {
{{/mostInnerItems}}
{{/isContainer}}
{{/isEnum}}
{{/isModel}}
{{/vars}}
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,24 @@ class _${{classname}}Serializer implements StructuredSerializer<{{classname}}> {
{{#isContainer}}
result.{{{name}}}.replace(valueDes);
{{/isContainer}}
{{^isContainer}}
{{#isEnum}}
result.{{{name}}} = valueDes;
{{/isEnum}}
{{^isEnum}}
{{#isModel}}
{{#isPrimitiveType}}
{{! These are models that have nee manually marked as primitive via generator param. }}
{{! These are models that have been manually marked as primitive via generator param. }}
result.{{{name}}} = valueDes;
{{/isPrimitiveType}}
{{^isPrimitiveType}}
result.{{{name}}}.replace(valueDes);
{{/isPrimitiveType}}
{{/isModel}}
{{^isContainer}}
{{^isModel}}
result.{{{name}}} = valueDes;
{{/isModel}}
{{/isEnum}}
{{/isContainer}}
break;
{{/vars}}
Expand All @@ -132,6 +137,7 @@ class _${{classname}}Serializer implements StructuredSerializer<{{classname}}> {
enum.mustache template.
}}
{{#vars}}
{{^isModel}}
{{#isEnum}}
{{^isContainer}}

Expand All @@ -144,4 +150,5 @@ class _${{classname}}Serializer implements StructuredSerializer<{{classname}}> {
{{/mostInnerItems}}
{{/isContainer}}
{{/isEnum}}
{{/isModel}}
{{/vars}}
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ class {{{classname}}} {
};
}
{{#vars}}
{{^isModel}}
{{#isEnum}}
{{^isContainer}}

Expand All @@ -289,4 +290,5 @@ class {{{classname}}} {
{{/mostInnerItems}}
{{/isContainer}}
{{/isEnum}}
{{/isModel}}
{{/vars}}
Original file line number Diff line number Diff line change
Expand Up @@ -1341,8 +1341,17 @@ components:
type: integer
format: int32
description: User Status
userType:
Copy link
Member

Choose a reason for hiding this comment

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

FYI. I'll move these to new model instead of modifying "User"

allOf:
- $ref: '#/components/schemas/UserType'
xml:
name: User
UserType:
type: string
title: UserType
enum:
- admin
- user
Tag:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ docs/StoreApi.md
docs/Tag.md
docs/User.md
docs/UserApi.md
docs/UserType.md
git_push.sh
mono_nunit_test.sh
src/Org.OpenAPITools.Test/packages.config
Expand Down Expand Up @@ -122,6 +123,7 @@ src/Org.OpenAPITools/Model/Return.cs
src/Org.OpenAPITools/Model/SpecialModelName.cs
src/Org.OpenAPITools/Model/Tag.cs
src/Org.OpenAPITools/Model/User.cs
src/Org.OpenAPITools/Model/UserType.cs
src/Org.OpenAPITools/Org.OpenAPITools.csproj
src/Org.OpenAPITools/Org.OpenAPITools.nuspec
src/Org.OpenAPITools/Properties/AssemblyInfo.cs
Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/csharp/OpenAPIClient/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ Class | Method | HTTP request | Description
- [Model.SpecialModelName](docs/SpecialModelName.md)
- [Model.Tag](docs/Tag.md)
- [Model.User](docs/User.md)
- [Model.UserType](docs/UserType.md)


## Documentation for Authorization
Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/csharp/OpenAPIClient/docs/User.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Name | Type | Description | Notes
**Password** | **string** | | [optional]
**Phone** | **string** | | [optional]
**UserStatus** | **int** | User Status | [optional]
**UserType** | **UserType** | | [optional]

[[Back to Model list]](../README.md#documentation-for-models)
[[Back to API list]](../README.md#documentation-for-api-endpoints)
Expand Down
12 changes: 12 additions & 0 deletions samples/client/petstore/csharp/OpenAPIClient/docs/UserType.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

# Org.OpenAPITools.Model.UserType

## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------

[[Back to Model list]](../README.md#documentation-for-models)
[[Back to API list]](../README.md#documentation-for-api-endpoints)
[[Back to README]](../README.md)

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* OpenAPI Petstore
*
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://github.com/openapitools/openapi-generator.git
*/


using NUnit.Framework;

using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using Org.OpenAPITools.Api;
using Org.OpenAPITools.Model;
using Org.OpenAPITools.Client;
using System.Reflection;
using Newtonsoft.Json;

namespace Org.OpenAPITools.Test
{
/// <summary>
/// Class for testing UserType
/// </summary>
/// <remarks>
/// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech).
/// Please update the test case below to test the model.
/// </remarks>
public class UserTypeTests
{
// TODO uncomment below to declare an instance variable for UserType
//private UserType instance;

/// <summary>
/// Setup before each test
/// </summary>
[SetUp]
public void Init()
{
// TODO uncomment below to create an instance of UserType
//instance = new UserType();
}

/// <summary>
/// Clean up after each test
/// </summary>
[TearDown]
public void Cleanup()
{

}

/// <summary>
/// Test an instance of UserType
/// </summary>
[Test]
public void UserTypeInstanceTest()
{
// TODO uncomment below to test "IsInstanceOf" UserType
//Assert.IsInstanceOf(typeof(UserType), instance);
}



}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ namespace Org.OpenAPITools.Model
[DataContract]
public partial class User : IEquatable<User>, IValidatableObject
{
/// <summary>
/// Gets or Sets UserType
/// </summary>
[DataMember(Name="userType", EmitDefaultValue=true)]
public UserType? UserType { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="User" /> class.
/// </summary>
Expand All @@ -41,8 +46,10 @@ public partial class User : IEquatable<User>, IValidatableObject
/// <param name="password">password.</param>
/// <param name="phone">phone.</param>
/// <param name="userStatus">User Status.</param>
public User(long id = default(long), string username = default(string), string firstName = default(string), string lastName = default(string), string email = default(string), string password = default(string), string phone = default(string), int userStatus = default(int))
/// <param name="userType">userType.</param>
public User(long id = default(long), string username = default(string), string firstName = default(string), string lastName = default(string), string email = default(string), string password = default(string), string phone = default(string), int userStatus = default(int), UserType? userType = default(UserType?))
{
this.UserType = userType;
this.Id = id;
this.Username = username;
this.FirstName = firstName;
Expand All @@ -51,6 +58,7 @@ public partial class User : IEquatable<User>, IValidatableObject
this.Password = password;
this.Phone = phone;
this.UserStatus = userStatus;
this.UserType = userType;
}

/// <summary>
Expand Down Expand Up @@ -102,6 +110,7 @@ public partial class User : IEquatable<User>, IValidatableObject
[DataMember(Name="userStatus", EmitDefaultValue=false)]
public int UserStatus { get; set; }


/// <summary>
/// Returns the string presentation of the object
/// </summary>
Expand All @@ -118,6 +127,7 @@ public override string ToString()
sb.Append(" Password: ").Append(Password).Append("\n");
sb.Append(" Phone: ").Append(Phone).Append("\n");
sb.Append(" UserStatus: ").Append(UserStatus).Append("\n");
sb.Append(" UserType: ").Append(UserType).Append("\n");
sb.Append("}\n");
return sb.ToString();
}
Expand Down Expand Up @@ -191,6 +201,11 @@ public bool Equals(User input)
this.UserStatus == input.UserStatus ||
(this.UserStatus != null &&
this.UserStatus.Equals(input.UserStatus))
) &&
(
this.UserType == input.UserType ||
(this.UserType != null &&
this.UserType.Equals(input.UserType))
);
}

Expand Down Expand Up @@ -219,6 +234,8 @@ public override int GetHashCode()
hashCode = hashCode * 59 + this.Phone.GetHashCode();
if (this.UserStatus != null)
hashCode = hashCode * 59 + this.UserStatus.GetHashCode();
if (this.UserType != null)
hashCode = hashCode * 59 + this.UserType.GetHashCode();
return hashCode;
}
}
Expand Down
Loading