From d4b8ff60a13a33124468da42ff7aa6d32a92ddc9 Mon Sep 17 00:00:00 2001 From: Justin Black Date: Mon, 27 Sep 2021 16:12:40 -0700 Subject: [PATCH] [Java] Fixes schema class type booleans for composed schemas (#10334) * Adds get/setIsString interface to IJsonSchemaValidationProperties * Adds get/set isNumber interface in IJsonSchemaValidationProperties * Adds get/set isAnyType in IJsonSchemaValidationProperties * Adds and uses ModelUtils.isAnyType, adds setTypeProperties * Adds missing descriptions of isAnyType parameters * Uses ModelUtils.isAnyType * Samples regenerated * Moves isArray handling higher up in fromProperty * Moves isAnyTypeSchema handling higher up in fromProperty * Moves isFreeFormObject handling higher up in fromProperty * Refactors fromProperties, updates tests * Fixes the fromProperty refactor, tests now pass * Uses setTypeProperties to set isNumber, isNull, isArray, and isUnboundedInteger * Sets isAnyType in setTypeProperties * Sets isMap in setTypeProperties * Sets property.isPrimitiveType in isFreeFormObject, tweaks if condition order * Adds fix for JavaClientCodegenTest.testJdkHttpClientWithAndWithoutDiscriminator * Refactors fromProperty * Adds updatePropertyForObject updatePropertyForAnyType * Sets binary and file types to not be strings * Updates samples * Adds updatePropertyForString * Adds testComposedPropertyTypes * Fixes python test * Samples updated * Switches all isAnyTypeSchema usages to ModelUtils.isAnyType * Refactors model enum handling higher up * Moves m.dataType assignent higher into fromModel * Moves m.isNullable setting higher into isModel * Adds updateModelForComposedSchema * Further fromModel refactoring, all schema checks are now at the same indentation level * Further refactors fromModel, adds isTypeObjectSchema block * Moves addVars into anyType or objectType blocks in fromModel * Turns off isNullable n isAnyType array * Fixes typescript CodegenParameers * Adds updatePropertyForAnyType to typescript-axios so property.isNullable will be false for AnyType * Adds testComposedModelTypes * Updates ComposedAnyType schema * Fixes tests for JavaJAXRSCXF by adding updateModelForObject method * Updates go and csharp to handle object model differently * Adds updateModelForAnyType * Fixes name reference * Adds testComposedResponseTypes * Refactoring fromResponse * Further refactoring of fromResponse * Uses setTypeProperties in fromResponse * Tests now pass for testComposedResponseTypes * Sets COdegenResponse dataType using getTypeDeclaration * Begins refactoring of fromRequestBody * Adds updateResponseBodyForPrimitiveType * Adds all needed type if else blocks in fromRequestBody * Fixes JavaJAXRSCXFExtServerCodegenTests * Fixes RubyClientCodegenTests * Adds fixes for clients that need custom isMap for body parameters * Ruby broken, samples regened, debugging * Adds updateRequestBodyForArray, renames updateRequest.. methods * Samples regenerated * Removes changes from Ruby generator * Reverts RubyClientCodegen.java * Reverts changes to GoClientCodegen.java * Reverts PowerShellClientCodegen.java * Reverts CrystalClientCodegen.java * Removes updateRequestBodyForObject from JavaCXFServerCodegen.java * Adds comment about refed models * Tweaks made to fromProperties to add an explanatory comment * Updates RustServer to have ByteArray request bodies not be strings * Sets types in fromFormProperty * Adds testComposedRequestBodyTypes * Fixes when validation syncing is done in syncValidationProperties * Removes redundant validation code from fromParameter * Moves parameter inX setting higher up before schema logic in fromParameter * More refactoring in fromParameter, uses early return to reduce levels of indentation * Removes setParameterBooleanFlagWithCodegenProperty from updateRequestBodyForArray * Removes setParameterBooleanFlagWithCodegenProperty from updateRequestBodyForObject * Removes setParameterBooleanFlagWithCodegenProperty from updateRequestBodyForPrimitiveType * Removes setParameterBooleanFlagWithCodegenProperty from updateRequestBodyForMap * Removes setParameterBooleanFlagWithCodegenProperty from addBodyModelSchema * Removes setParameterBooleanFlagWithCodegenProperty from fromFormProperty * Refactors parameter array handling code into fromFormProperty * Simplifies fromRequestBodyToFormParameters * Removes setParameterBooleanFlagWithCodegenProperty from fromParameter * Adds deprecated docstring to setParameterBooleanFlagWithCodegenProperty * Refactors ModelUtils.isFileSchema out of string schema check * Removes ModelUtils.isFileSchema from RustServer updateRequestBodyForString * Improves comment text * Fixes RustServer uuid type setting for CodegenParameter * Removes unneeded parens * Fixes array property examples * Removes unused code * Renames variable to itemsProperty * Adds testComposedRequestQueryParamTypes * Adds updatePropertyForAnyType to rustserver will not have changed model properties * Hoists arrayInnerProperty._enum into parameter for html2 generator * Moves turning string type off into the codegen files * Adds two more missing locations in rustserver * Moves addVarsRequiredVarsAdditionalProps into anytype and objecttype handling * More refactoring of where addVarsRequiredVarsAdditionalProps is used * Samples regenerated --- .../openapitools/codegen/CodegenModel.java | 30 +- .../codegen/CodegenParameter.java | 24 + .../openapitools/codegen/CodegenProperty.java | 24 + .../openapitools/codegen/CodegenResponse.java | 24 + .../openapitools/codegen/DefaultCodegen.java | 1931 +++++++++-------- .../IJsonSchemaValidationProperties.java | 77 + .../codegen/languages/AbstractGoCodegen.java | 2 +- .../languages/CSharpNetCoreClientCodegen.java | 25 + .../codegen/languages/GoServerCodegen.java | 27 + .../languages/JavaCXFServerCodegen.java | 29 +- .../languages/PythonClientCodegen.java | 4 +- .../codegen/languages/RustServerCodegen.java | 89 + .../TypeScriptAxiosClientCodegen.java | 17 + .../languages/TypeScriptClientCodegen.java | 2 +- .../codegen/utils/ModelUtils.java | 40 +- .../codegen/DefaultCodegenTest.java | 210 ++ .../codegen/java/JavaClientCodegenTest.java | 6 + .../codegen/python/PythonClientTest.java | 2 +- .../src/test/resources/3_0/issue_10330.yaml | 289 +++ .../3_0/issue_8052_recursive_model.yaml | 18 +- .../docs/FakeApi.md | 8 +- .../docs/PetApi.md | 4 +- .../OpenAPIClient-httpclient/docs/FakeApi.md | 8 +- .../OpenAPIClient-httpclient/docs/PetApi.md | 4 +- .../OpenAPIClient-net47/docs/FakeApi.md | 8 +- .../OpenAPIClient-net47/docs/PetApi.md | 4 +- .../OpenAPIClient-net5.0/docs/FakeApi.md | 8 +- .../OpenAPIClient-net5.0/docs/PetApi.md | 4 +- .../OpenAPIClient/docs/FakeApi.md | 8 +- .../OpenAPIClient/docs/PetApi.md | 4 +- .../OpenAPIClientCore/docs/FakeApi.md | 8 +- .../OpenAPIClientCore/docs/PetApi.md | 4 +- .../OpenAPIClientCoreAndNet47/docs/PetApi.md | 4 +- .../csharp/OpenAPIClient/docs/FakeApi.md | 8 +- .../csharp/OpenAPIClient/docs/PetApi.md | 4 +- .../java/apache-httpclient/docs/FakeApi.md | 2 +- .../java/google-api-client/docs/FakeApi.md | 2 +- .../petstore/java/jersey1/docs/FakeApi.md | 2 +- .../docs/FakeApi.md | 2 +- .../java/jersey2-java8/docs/FakeApi.md | 2 +- .../java/native-async/docs/FakeApi.md | 4 +- .../petstore/java/native/docs/FakeApi.md | 4 +- .../docs/FakeApi.md | 2 +- .../docs/FakeApi.md | 2 +- .../petstore/java/okhttp-gson/docs/FakeApi.md | 2 +- .../petstore/java/resteasy/docs/FakeApi.md | 2 +- .../java/resttemplate-withXml/docs/FakeApi.md | 2 +- .../java/resttemplate/docs/FakeApi.md | 2 +- .../java/retrofit2-play26/docs/FakeApi.md | 2 +- .../petstore/java/retrofit2/docs/FakeApi.md | 2 +- .../java/retrofit2rx2/docs/FakeApi.md | 2 +- .../java/retrofit2rx3/docs/FakeApi.md | 2 +- .../java/vertx-no-nullable/docs/FakeApi.md | 2 +- .../petstore/java/vertx/docs/FakeApi.md | 2 +- .../petstore/java/webclient/docs/FakeApi.md | 2 +- .../petstore/javascript-es6/docs/FakeApi.md | 2 +- .../javascript-promise-es6/docs/FakeApi.md | 2 +- .../php/OpenAPIClient-php/docs/Api/FakeApi.md | 2 +- .../client/petstore/python/docs/FakeApi.md | 4 +- samples/client/petstore/python/docs/PetApi.md | 4 +- .../docs/FakeApi.md | 4 +- .../docs/PetApi.md | 4 +- .../api.ts | 2 +- .../client/elm/src/Api/Request/Default.elm | 2 +- .../petstore_client_lib_fake/doc/FakeApi.md | 2 +- .../petstore_client_lib_fake/doc/FakeApi.md | 2 +- .../petstore_client_lib_fake/doc/FakeApi.md | 2 +- .../doc/FakeApi.md | 2 +- .../java/jersey2-java8/docs/FakeApi.md | 2 +- .../client/petstore/python/docs/FakeApi.md | 16 +- .../builds/composed-schemas/DefaultApi.md | 6 +- 71 files changed, 2090 insertions(+), 970 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/issue_10330.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java index feb8420a2c3..ab9f23fba67 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java @@ -161,6 +161,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { private boolean isModel; private boolean hasRequiredVars; private boolean hasDiscriminatorWithNonEmptyMapping; + private boolean isAnyType; public String getAdditionalPropertiesType() { return additionalPropertiesType; @@ -785,6 +786,30 @@ public class CodegenModel implements IJsonSchemaValidationProperties { this.hasDiscriminatorWithNonEmptyMapping = hasDiscriminatorWithNonEmptyMapping; } + @Override + public boolean getIsString() { return isString; } + + @Override + public void setIsString(boolean isString) { + this.isString = isString; + } + + @Override + public boolean getIsNumber() { return isNumber; } + + @Override + public void setIsNumber(boolean isNumber) { + this.isNumber = isNumber; + } + + @Override + public boolean getIsAnyType() { return isAnyType; } + + @Override + public void setIsAnyType(boolean isAnyType) { + this.isAnyType = isAnyType; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -819,6 +844,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { isNull == that.isNull && hasValidation == that.hasValidation && hasDiscriminatorWithNonEmptyMapping == that.getHasDiscriminatorWithNonEmptyMapping() && + getIsAnyType() == that.getIsAnyType() && getAdditionalPropertiesIsAnyType() == that.getAdditionalPropertiesIsAnyType() && getUniqueItems() == that.getUniqueItems() && getExclusiveMinimum() == that.getExclusiveMinimum() && @@ -895,7 +921,8 @@ public class CodegenModel implements IJsonSchemaValidationProperties { getAdditionalPropertiesType(), getMaxProperties(), getMinProperties(), getUniqueItems(), getMaxItems(), getMinItems(), getMaxLength(), getMinLength(), getExclusiveMinimum(), getExclusiveMaximum(), getMinimum(), getMaximum(), getPattern(), getMultipleOf(), getItems(), getAdditionalProperties(), getIsModel(), - getAdditionalPropertiesIsAnyType(), hasDiscriminatorWithNonEmptyMapping, anyOfProps, oneOfProps, allOfProps); + getAdditionalPropertiesIsAnyType(), hasDiscriminatorWithNonEmptyMapping, anyOfProps, oneOfProps, allOfProps, + isAnyType); } @Override @@ -989,6 +1016,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { sb.append(", hasValidation='").append(hasValidation); sb.append(", getAdditionalPropertiesIsAnyType=").append(getAdditionalPropertiesIsAnyType()); sb.append(", getHasDiscriminatorWithNonEmptyMapping=").append(hasDiscriminatorWithNonEmptyMapping); + sb.append(", getIsAnyType=").append(getIsAnyType()); sb.append('}'); return sb.toString(); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java index 6c0aaf869da..ebd01afdfd2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java @@ -682,5 +682,29 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { public void setHasDiscriminatorWithNonEmptyMapping(boolean hasDiscriminatorWithNonEmptyMapping) { this.hasDiscriminatorWithNonEmptyMapping = hasDiscriminatorWithNonEmptyMapping; } + + @Override + public boolean getIsString() { return isString; } + + @Override + public void setIsString(boolean isString) { + this.isString = isString; + } + + @Override + public boolean getIsNumber() { return isNumber; } + + @Override + public void setIsNumber(boolean isNumber) { + this.isNumber = isNumber; + } + + @Override + public boolean getIsAnyType() { return isAnyType; } + + @Override + public void setIsAnyType(boolean isAnyType) { + this.isAnyType = isAnyType; + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java index 8fe4c34ebb1..ed1636fc6d5 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java @@ -763,6 +763,30 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti this.hasDiscriminatorWithNonEmptyMapping = hasDiscriminatorWithNonEmptyMapping; } + @Override + public boolean getIsString() { return isString; } + + @Override + public void setIsString(boolean isString) { + this.isString = isString; + } + + @Override + public boolean getIsNumber() { return isNumber; } + + @Override + public void setIsNumber(boolean isNumber) { + this.isNumber = isNumber; + } + + @Override + public boolean getIsAnyType() { return isAnyType; } + + @Override + public void setIsAnyType(boolean isAnyType) { + this.isAnyType = isAnyType; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("CodegenProperty{"); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java index 022933ebe4c..1a99e774e59 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java @@ -546,4 +546,28 @@ public class CodegenResponse implements IJsonSchemaValidationProperties { public void setHasDiscriminatorWithNonEmptyMapping(boolean hasDiscriminatorWithNonEmptyMapping) { this.hasDiscriminatorWithNonEmptyMapping = hasDiscriminatorWithNonEmptyMapping; } + + @Override + public boolean getIsString() { return isString; } + + @Override + public void setIsString(boolean isString) { + this.isString = isString; + } + + @Override + public boolean getIsNumber() { return isNumber; } + + @Override + public void setIsNumber(boolean isNumber) { + this.isNumber = isNumber; + } + + @Override + public boolean getIsAnyType() { return isAnyType; } + + @Override + public void setIsAnyType(boolean isAnyType) { + this.isAnyType = isAnyType; + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 68f7412a550..65d34bdf664 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -2214,7 +2214,7 @@ public class DefaultCodegen implements CodegenConfig { return "object"; } else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) { // having property implies it's a model return "object"; - } else if (isAnyTypeSchema(schema)) { + } else if (ModelUtils.isAnyType(schema)) { return "AnyType"; } else if (StringUtils.isNotEmpty(schema.getType())) { if (!importMapping.containsKey(schema.getType())) { @@ -2381,6 +2381,242 @@ public class DefaultCodegen implements CodegenConfig { Map schemaCodegenPropertyCache = new HashMap(); + private void updateModelForComposedSchema(CodegenModel m, Schema schema, Map allDefinitions) { + final ComposedSchema composed = (ComposedSchema) schema; + Map properties = new LinkedHashMap(); + List required = new ArrayList(); + Map allProperties = new LinkedHashMap(); + List allRequired = new ArrayList(); + + // if schema has properties outside of allOf/oneOf/anyOf also add them to m + if (composed.getProperties() != null && !composed.getProperties().isEmpty()) { + if (composed.getOneOf() != null && !composed.getOneOf().isEmpty()) { + LOGGER.warn("'oneOf' is intended to include only the additional optional OAS extension discriminator object. " + + "For more details, see https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.2.1.3 and the OAS section on 'Composition and Inheritance'."); + } + addVars(m, unaliasPropertySchema(composed.getProperties()), composed.getRequired(), null, null); + } + + // parent model + final String parentName = ModelUtils.getParentName(composed, allDefinitions); + final List allParents = ModelUtils.getAllParentsName(composed, allDefinitions, false); + final Schema parent = StringUtils.isBlank(parentName) || allDefinitions == null ? null : allDefinitions.get(parentName); + + // TODO revise the logic below to set discriminator, xml attributes + if (supportsInheritance || supportsMixins) { + m.allVars = new ArrayList(); + if (composed.getAllOf() != null) { + int modelImplCnt = 0; // only one inline object allowed in a ComposedModel + int modelDiscriminators = 0; // only one discriminator allowed in a ComposedModel + for (Schema innerSchema : composed.getAllOf()) { // TODO need to work with anyOf, oneOf as well + if (m.discriminator == null && innerSchema.getDiscriminator() != null) { + LOGGER.debug("discriminator is set to null (not correctly set earlier): {}", m.name); + m.setDiscriminator(createDiscriminator(m.name, innerSchema, this.openAPI)); + if (!this.getLegacyDiscriminatorBehavior()) { + m.addDiscriminatorMappedModelsImports(); + } + modelDiscriminators++; + } + + if (innerSchema.getXml() != null) { + m.xmlPrefix = innerSchema.getXml().getPrefix(); + m.xmlNamespace = innerSchema.getXml().getNamespace(); + m.xmlName = innerSchema.getXml().getName(); + } + if (modelDiscriminators > 1) { + LOGGER.error("Allof composed schema is inheriting >1 discriminator. Only use one discriminator: {}", composed); + } + + if (modelImplCnt++ > 1) { + LOGGER.warn("More than one inline schema specified in allOf:. Only the first one is recognized. All others are ignored."); + break; // only one schema with discriminator allowed in allOf + } + } + } + } + + // interfaces (schemas defined in allOf, anyOf, oneOf) + List interfaces = ModelUtils.getInterfaces(composed); + List anyOfProps = new ArrayList<>(); + List allOfProps = new ArrayList<>(); + List oneOfProps = new ArrayList<>(); + if (!interfaces.isEmpty()) { + // m.interfaces is for backward compatibility + if (m.interfaces == null) + m.interfaces = new ArrayList(); + + for (Schema interfaceSchema : interfaces) { + interfaceSchema = unaliasSchema(interfaceSchema, importMapping); + + if (StringUtils.isBlank(interfaceSchema.get$ref())) { + // primitive type + String languageType = getTypeDeclaration(interfaceSchema); + CodegenProperty interfaceProperty = fromProperty(languageType, interfaceSchema); + if (ModelUtils.isArraySchema(interfaceSchema) || ModelUtils.isMapSchema(interfaceSchema)) { + while (interfaceProperty != null) { + addImport(m, interfaceProperty.complexType); + interfaceProperty = interfaceProperty.items; + } + } + + if (composed.getAnyOf() != null) { + if (m.anyOf.contains(languageType)) { + LOGGER.warn("{} (anyOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType); + } else { + m.anyOf.add(languageType); + anyOfProps.add(interfaceProperty); + + } + } else if (composed.getOneOf() != null) { + if (m.oneOf.contains(languageType)) { + LOGGER.warn("{} (oneOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType); + } else { + m.oneOf.add(languageType); + oneOfProps.add(interfaceProperty); + } + } else if (composed.getAllOf() != null) { + // no need to add primitive type to allOf, which should comprise of schemas (models) only + } else { + LOGGER.error("Composed schema has incorrect anyOf, allOf, oneOf defined: {}", composed); + } + continue; + } + + // the rest of the section is for model + Schema refSchema = null; + String ref = ModelUtils.getSimpleRef(interfaceSchema.get$ref()); + if (allDefinitions != null) { + refSchema = allDefinitions.get(ref); + } + final String modelName = toModelName(ref); + CodegenProperty interfaceProperty = fromProperty(modelName, interfaceSchema); + m.interfaces.add(modelName); + addImport(m, modelName); + if (allDefinitions != null && refSchema != null) { + if (allParents.contains(ref) && supportsMultipleInheritance) { + // multiple inheritance + addProperties(allProperties, allRequired, refSchema); + } else if (parentName != null && parentName.equals(ref) && supportsInheritance) { + // single inheritance + addProperties(allProperties, allRequired, refSchema); + } else { + // composition + addProperties(properties, required, refSchema); + addProperties(allProperties, allRequired, refSchema); + } + } + + if (composed.getAnyOf() != null) { + m.anyOf.add(modelName); + anyOfProps.add(interfaceProperty); + } else if (composed.getOneOf() != null) { + m.oneOf.add(modelName); + oneOfProps.add(interfaceProperty); + } else if (composed.getAllOf() != null) { + m.allOf.add(modelName); + allOfProps.add(interfaceProperty); + } else { + LOGGER.error("Composed schema has incorrect anyOf, allOf, oneOf defined: {}", composed); + } + } + } + + m.oneOfProps = oneOfProps; + m.allOfProps = allOfProps; + m.anyOfProps = anyOfProps; + + if (parent != null && composed.getAllOf() != null) { // set parent for allOf only + m.parentSchema = parentName; + m.parent = toModelName(parentName); + + if (supportsMultipleInheritance) { + m.allParents = new ArrayList(); + for (String pname : allParents) { + String pModelName = toModelName(pname); + m.allParents.add(pModelName); + addImport(m, pModelName); + } + } else { // single inheritance + addImport(m, m.parent); + } + } + + // child schema (properties owned by the schema itself) + for (Schema component : interfaces) { + if (component.get$ref() == null) { + if (component != null) { + // component is the child schema + addProperties(properties, required, component); + + // includes child's properties (all, required) in allProperties, allRequired + addProperties(allProperties, allRequired, component); + } + break; // at most one child only + } + } + + if (composed.getRequired() != null) { + required.addAll(composed.getRequired()); + allRequired.addAll(composed.getRequired()); + } + + addVars(m, unaliasPropertySchema(properties), required, unaliasPropertySchema(allProperties), allRequired); + + // Per OAS specification, composed schemas may use the 'additionalProperties' keyword. + if (supportsAdditionalPropertiesWithComposedSchema) { + // Process the schema specified with the 'additionalProperties' keyword. + // This will set the 'CodegenModel.additionalPropertiesType' field + // and potentially 'Codegen.parent'. + // + // Note: it's not a good idea to use single class inheritance to implement + // the 'additionalProperties' keyword. Code generators that use single class + // inheritance sometimes use the 'Codegen.parent' field to implement the + // 'additionalProperties' keyword. However, that would be in conflict with + // 'allOf' composed schemas, because these code generators also want to set + // 'Codegen.parent' to the first child schema of the 'allOf' schema. + addAdditionPropertiesToCodeGenModel(m, schema); + } + + if (Boolean.TRUE.equals(schema.getNullable())) { + m.isNullable = Boolean.TRUE; + } + // end of code block for composed schema + } + + protected void updateModelForObject(CodegenModel m, Schema schema) { + if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) { + // passing null to allProperties and allRequired as there's no parent + addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null); + } + if (ModelUtils.isMapSchema(schema)) { + // an object or anyType composed schema that has additionalProperties set + addAdditionPropertiesToCodeGenModel(m, schema); + } else if (ModelUtils.isFreeFormObject(openAPI, schema)) { + // non-composed object type with no properties + additionalProperties + // additionalProperties must be null, ObjectSchema, or empty Schema + addAdditionPropertiesToCodeGenModel(m, schema); + } + } + + protected void updateModelForAnyType(CodegenModel m, Schema schema) { + // The 'null' value is allowed when the OAS schema is 'any type'. + // See https://github.com/OAI/OpenAPI-Specification/issues/1389 + if (Boolean.FALSE.equals(schema.getNullable())) { + LOGGER.error("Schema '{}' is any type, which includes the 'null' value. 'nullable' cannot be set to 'false'", m.name); + } + // m.isNullable = true; + if (ModelUtils.isMapSchema(schema)) { + // an object or anyType composed schema that has additionalProperties set + addAdditionPropertiesToCodeGenModel(m, schema); + m.isMap = true; + } + if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) { + // passing null to allProperties and allRequired as there's no parent + addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null); + } + } + + /** * Convert OAS Model object to Codegen Model object. * @@ -2438,278 +2674,70 @@ public class DefaultCodegen implements CodegenConfig { m.xmlNamespace = schema.getXml().getNamespace(); m.xmlName = schema.getXml().getName(); } - if (isAnyTypeSchema(schema)) { - // The 'null' value is allowed when the OAS schema is 'any type'. - // See https://github.com/OAI/OpenAPI-Specification/issues/1389 - if (Boolean.FALSE.equals(schema.getNullable())) { - LOGGER.error("Schema '{}' is any type, which includes the 'null' value. 'nullable' cannot be set to 'false'", name); - } - m.isNullable = true; + if (!ModelUtils.isAnyType(schema) && !ModelUtils.isTypeObjectSchema(schema) && !ModelUtils.isArraySchema(schema) && schema.get$ref() == null && schema.getEnum() != null && !schema.getEnum().isEmpty()) { + // TODO remove the anyType check here in the future ANyType models can have enums defined + m.isEnum = true; + // comment out below as allowableValues is not set in post processing model enum + m.allowableValues = new HashMap(); + m.allowableValues.put("values", schema.getEnum()); } + if (!ModelUtils.isArraySchema(schema)) { + m.dataType = getSchemaType(schema); + } + if (!ModelUtils.isAnyType(schema) && Boolean.TRUE.equals(schema.getNullable())) { + m.isNullable = Boolean.TRUE; + } + + m.setTypeProperties(schema); if (ModelUtils.isArraySchema(schema)) { - m.isArray = true; CodegenProperty arrayProperty = fromProperty(name, schema); m.setItems(arrayProperty.items); m.arrayModelType = arrayProperty.complexType; addParentContainer(m, name, schema); - } else if (ModelUtils.isNullType(schema)) { - m.isNull = true; - } else if (schema instanceof ComposedSchema) { - final ComposedSchema composed = (ComposedSchema) schema; - Map properties = new LinkedHashMap(); - List required = new ArrayList(); - Map allProperties = new LinkedHashMap(); - List allRequired = new ArrayList(); + } else if (ModelUtils.isIntegerSchema(schema)) { // integer type + // NOTE: Integral schemas as CodegenModel is a rare use case and may be removed at a later date. - // if schema has properties outside of allOf/oneOf/anyOf also add them to m - if (composed.getProperties() != null && !composed.getProperties().isEmpty()) { - if (composed.getOneOf() != null && !composed.getOneOf().isEmpty()) { - LOGGER.warn("'oneOf' is intended to include only the additional optional OAS extension discriminator object. " + - "For more details, see https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.2.1.3 and the OAS section on 'Composition and Inheritance'."); - } - addVars(m, unaliasPropertySchema(composed.getProperties()), composed.getRequired(), null, null); - } - - // parent model - final String parentName = ModelUtils.getParentName(composed, allDefinitions); - final List allParents = ModelUtils.getAllParentsName(composed, allDefinitions, false); - final Schema parent = StringUtils.isBlank(parentName) || allDefinitions == null ? null : allDefinitions.get(parentName); - - // TODO revise the logic below to set discriminator, xml attributes - if (supportsInheritance || supportsMixins) { - m.allVars = new ArrayList(); - if (composed.getAllOf() != null) { - int modelImplCnt = 0; // only one inline object allowed in a ComposedModel - int modelDiscriminators = 0; // only one discriminator allowed in a ComposedModel - for (Schema innerSchema : composed.getAllOf()) { // TODO need to work with anyOf, oneOf as well - if (m.discriminator == null && innerSchema.getDiscriminator() != null) { - LOGGER.debug("discriminator is set to null (not correctly set earlier): {}", name); - m.setDiscriminator(createDiscriminator(name, innerSchema, this.openAPI)); - if (!this.getLegacyDiscriminatorBehavior()) { - m.addDiscriminatorMappedModelsImports(); - } - modelDiscriminators++; - } - - if (innerSchema.getXml() != null) { - m.xmlPrefix = innerSchema.getXml().getPrefix(); - m.xmlNamespace = innerSchema.getXml().getNamespace(); - m.xmlName = innerSchema.getXml().getName(); - } - if (modelDiscriminators > 1) { - LOGGER.error("Allof composed schema is inheriting >1 discriminator. Only use one discriminator: {}", composed); - } - - if (modelImplCnt++ > 1) { - LOGGER.warn("More than one inline schema specified in allOf:. Only the first one is recognized. All others are ignored."); - break; // only one schema with discriminator allowed in allOf - } - } + m.isNumeric = Boolean.TRUE; + if (ModelUtils.isLongSchema(schema)) { // int64/long format + m.isLong = Boolean.TRUE; + } else { + m.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int + if (ModelUtils.isShortSchema(schema)) { // int32 + m.setIsShort(Boolean.TRUE); } } - - // interfaces (schemas defined in allOf, anyOf, oneOf) - List interfaces = ModelUtils.getInterfaces(composed); - List anyOfProps = new ArrayList<>(); - List allOfProps = new ArrayList<>(); - List oneOfProps = new ArrayList<>(); - if (!interfaces.isEmpty()) { - // m.interfaces is for backward compatibility - if (m.interfaces == null) - m.interfaces = new ArrayList(); - - for (Schema interfaceSchema : interfaces) { - interfaceSchema = unaliasSchema(interfaceSchema, importMapping); - - if (StringUtils.isBlank(interfaceSchema.get$ref())) { - // primitive type - String languageType = getTypeDeclaration(interfaceSchema); - CodegenProperty interfaceProperty = fromProperty(languageType, interfaceSchema); - if (ModelUtils.isArraySchema(interfaceSchema) || ModelUtils.isMapSchema(interfaceSchema)) { - while (interfaceProperty != null) { - addImport(m, interfaceProperty.complexType); - interfaceProperty = interfaceProperty.items; - } - } - - if (composed.getAnyOf() != null) { - if (m.anyOf.contains(languageType)) { - LOGGER.warn("{} (anyOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType); - } else { - m.anyOf.add(languageType); - anyOfProps.add(interfaceProperty); - - } - } else if (composed.getOneOf() != null) { - if (m.oneOf.contains(languageType)) { - LOGGER.warn("{} (oneOf schema) already has `{}` defined and therefore it's skipped.", m.name, languageType); - } else { - m.oneOf.add(languageType); - oneOfProps.add(interfaceProperty); - } - } else if (composed.getAllOf() != null) { - // no need to add primitive type to allOf, which should comprise of schemas (models) only - } else { - LOGGER.error("Composed schema has incorrect anyOf, allOf, oneOf defined: {}", composed); - } - continue; - } - - // the rest of the section is for model - Schema refSchema = null; - String ref = ModelUtils.getSimpleRef(interfaceSchema.get$ref()); - if (allDefinitions != null) { - refSchema = allDefinitions.get(ref); - } - final String modelName = toModelName(ref); - CodegenProperty interfaceProperty = fromProperty(modelName, interfaceSchema); - m.interfaces.add(modelName); - addImport(m, modelName); - if (allDefinitions != null && refSchema != null) { - if (allParents.contains(ref) && supportsMultipleInheritance) { - // multiple inheritance - addProperties(allProperties, allRequired, refSchema); - } else if (parentName != null && parentName.equals(ref) && supportsInheritance) { - // single inheritance - addProperties(allProperties, allRequired, refSchema); - } else { - // composition - addProperties(properties, required, refSchema); - addProperties(allProperties, allRequired, refSchema); - } - } - - if (composed.getAnyOf() != null) { - m.anyOf.add(modelName); - anyOfProps.add(interfaceProperty); - } else if (composed.getOneOf() != null) { - m.oneOf.add(modelName); - oneOfProps.add(interfaceProperty); - } else if (composed.getAllOf() != null) { - m.allOf.add(modelName); - allOfProps.add(interfaceProperty); - } else { - LOGGER.error("Composed schema has incorrect anyOf, allOf, oneOf defined: {}", composed); - } - } - } - - m.oneOfProps = oneOfProps; - m.allOfProps = allOfProps; - m.anyOfProps = anyOfProps; - - if (parent != null && composed.getAllOf() != null) { // set parent for allOf only - m.parentSchema = parentName; - m.parent = toModelName(parentName); - - if (supportsMultipleInheritance) { - m.allParents = new ArrayList(); - for (String pname : allParents) { - String pModelName = toModelName(pname); - m.allParents.add(pModelName); - addImport(m, pModelName); - } - } else { // single inheritance - addImport(m, m.parent); - } - } - - // child schema (properties owned by the schema itself) - for (Schema component : interfaces) { - if (component.get$ref() == null) { - if (component != null) { - // component is the child schema - addProperties(properties, required, component); - - // includes child's properties (all, required) in allProperties, allRequired - addProperties(allProperties, allRequired, component); - } - break; // at most one child only - } - } - - if (composed.getRequired() != null) { - required.addAll(composed.getRequired()); - allRequired.addAll(composed.getRequired()); - } - - addVars(m, unaliasPropertySchema(properties), required, unaliasPropertySchema(allProperties), allRequired); - - // Per OAS specification, composed schemas may use the 'additionalProperties' keyword. - if (supportsAdditionalPropertiesWithComposedSchema) { - // Process the schema specified with the 'additionalProperties' keyword. - // This will set the 'CodegenModel.additionalPropertiesType' field - // and potentially 'Codegen.parent'. - // - // Note: it's not a good idea to use single class inheritance to implement - // the 'additionalProperties' keyword. Code generators that use single class - // inheritance sometimes use the 'Codegen.parent' field to implement the - // 'additionalProperties' keyword. However, that would be in conflict with - // 'allOf' composed schemas, because these code generators also want to set - // 'Codegen.parent' to the first child schema of the 'allOf' schema. - addAdditionPropertiesToCodeGenModel(m, schema); - } - - if (Boolean.TRUE.equals(schema.getNullable())) { - m.isNullable = Boolean.TRUE; - } - // end of code block for composed schema - } else { - m.dataType = getSchemaType(schema); - if (schema.getEnum() != null && !schema.getEnum().isEmpty()) { - m.isEnum = true; - // comment out below as allowableValues is not set in post processing model enum - m.allowableValues = new HashMap(); - m.allowableValues.put("values", schema.getEnum()); - } - if (ModelUtils.isMapSchema(schema)) { - addAdditionPropertiesToCodeGenModel(m, schema); - m.isMap = true; - } else if (ModelUtils.isIntegerSchema(schema)) { // integer type - // NOTE: Integral schemas as CodegenModel is a rare use case and may be removed at a later date. - - m.isNumeric = Boolean.TRUE; - if (ModelUtils.isLongSchema(schema)) { // int64/long format - m.isLong = Boolean.TRUE; - } else { - m.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int - if (ModelUtils.isShortSchema(schema)) { // int32 - m.setIsShort(Boolean.TRUE); - } else { // unbounded integer - m.setIsUnboundedInteger(Boolean.TRUE); - } - } - } else if (ModelUtils.isDateTimeSchema(schema)) { + } else if (ModelUtils.isStringSchema(schema)) { + // NOTE: String schemas as CodegenModel is a rare use case and may be removed at a later date. + if (ModelUtils.isDateTimeSchema(schema)) { // NOTE: DateTime schemas as CodegenModel is a rare use case and may be removed at a later date. + m.setIsString(false); // for backward compatibility with 2.x m.isDateTime = Boolean.TRUE; } else if (ModelUtils.isDateSchema(schema)) { // NOTE: Date schemas as CodegenModel is a rare use case and may be removed at a later date. + m.setIsString(false); // for backward compatibility with 2.x m.isDate = Boolean.TRUE; - } else if (ModelUtils.isStringSchema(schema)) { - // NOTE: String schemas as CodegenModel is a rare use case and may be removed at a later date. - m.isString = Boolean.TRUE; - } else if (ModelUtils.isNumberSchema(schema)) { - // NOTE: Number schemas as CodegenModel is a rare use case and may be removed at a later date. - m.isNumeric = Boolean.TRUE; - if (ModelUtils.isFloatSchema(schema)) { // float - m.isFloat = Boolean.TRUE; - } else if (ModelUtils.isDoubleSchema(schema)) { // double - m.isDouble = Boolean.TRUE; - } else { // type is number and without format - m.isNumber = Boolean.TRUE; - } - } else if (ModelUtils.isBooleanSchema(schema)) { - m.isBoolean = Boolean.TRUE; - } else if (ModelUtils.isFreeFormObject(openAPI, schema)) { - addAdditionPropertiesToCodeGenModel(m, schema); } - - if (Boolean.TRUE.equals(schema.getNullable())) { - m.isNullable = Boolean.TRUE; + } else if (ModelUtils.isNumberSchema(schema)) { + // NOTE: Number schemas as CodegenModel is a rare use case and may be removed at a later date. + m.isNumeric = Boolean.TRUE; + if (ModelUtils.isFloatSchema(schema)) { // float + m.isFloat = Boolean.TRUE; + } else if (ModelUtils.isDoubleSchema(schema)) { // double + m.isDouble = Boolean.TRUE; } + } else if (ModelUtils.isAnyType(schema)) { + updateModelForAnyType(m, schema); + } else if (ModelUtils.isTypeObjectSchema(schema)) { + updateModelForObject(m, schema); + } else if (!ModelUtils.isNullType(schema)) { + // referenced models here, component that refs another component which is a model + // if a component references a schema which is not a generated model, the the refed schema will be loaded into + // schema by unaliasSchema and one of the above code paths will be taken + ; + } - // passing null to allProperties and allRequired as there's no parent - addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null); + if (schema instanceof ComposedSchema) { + updateModelForComposedSchema(m, schema, allDefinitions); } // remove duplicated properties @@ -2792,7 +2820,7 @@ public class DefaultCodegen implements CodegenConfig { } } else { addPropProp = fromProperty("", (Schema) schema.getAdditionalProperties()); - if (isAnyTypeSchema((Schema) schema.getAdditionalProperties())) { + if (ModelUtils.isAnyType((Schema) schema.getAdditionalProperties())) { additionalPropertiesIsAnyType = true; } } @@ -3254,6 +3282,90 @@ public class DefaultCodegen implements CodegenConfig { return camelize(toVarName(name)); } + protected void updatePropertyForMap(CodegenProperty property, Schema p) { + property.isContainer = true; + property.containerType = "map"; + // TODO remove this hack in the future, code should use minProperties and maxProperties for object schemas + property.minItems = p.getMinProperties(); + property.maxItems = p.getMaxProperties(); + + // handle inner property + Schema innerSchema = unaliasSchema(getAdditionalProperties(p), importMapping); + if (innerSchema == null) { + LOGGER.error("Undefined map inner type for `{}`. Default to String.", p.getName()); + innerSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to undefined type"); + p.setAdditionalProperties(innerSchema); + } + CodegenProperty cp = fromProperty("inner", innerSchema); + updatePropertyForMap(property, cp); + } + + protected void updatePropertyForObject(CodegenProperty property, Schema p) { + if (isFreeFormObject(p)) { + // non-composed object type with no properties + additionalProperties + // additionalProperties must be null, ObjectSchema, or empty Schema + property.isFreeFormObject = true; + if (languageSpecificPrimitives.contains(property.dataType)) { + property.isPrimitiveType = true; + } + if (ModelUtils.isMapSchema(p)) { + // an object or anyType composed schema that has additionalProperties set + updatePropertyForMap(property, p); + } else { + // ObjectSchema with additionalProperties = null, can be nullable + property.setIsMap(false); + } + } else if (ModelUtils.isMapSchema(p)) { + // an object or anyType composed schema that has additionalProperties set + updatePropertyForMap(property, p); + } + addVarsRequiredVarsAdditionalProps(p, property); + } + + protected void updatePropertyForAnyType(CodegenProperty property, Schema p) { + // The 'null' value is allowed when the OAS schema is 'any type'. + // See https://github.com/OAI/OpenAPI-Specification/issues/1389 + if (Boolean.FALSE.equals(p.getNullable())) { + LOGGER.warn("Schema '{}' is any type, which includes the 'null' value. 'nullable' cannot be set to 'false'", p.getName()); + } + property.isNullable = true; + if (languageSpecificPrimitives.contains(property.dataType)) { + property.isPrimitiveType = true; + } + if (ModelUtils.isMapSchema(p)) { + // an object or anyType composed schema that has additionalProperties set + // some of our code assumes that any type schema with properties defined will be a map + // even though it should allow in any type and have map constraints for properties + updatePropertyForMap(property, p); + } + addVarsRequiredVarsAdditionalProps(p, property); + } + + protected void updatePropertyForString(CodegenProperty property, Schema p) { + if (ModelUtils.isByteArraySchema(p)) { + property.isByteArray = true; + } else if (ModelUtils.isBinarySchema(p)) { + property.isBinary = true; + property.isFile = true; // file = binary in OAS3 + } else if (ModelUtils.isUUIDSchema(p)) { + property.isUuid = true; + } else if (ModelUtils.isURISchema(p)) { + property.isUri = true; + } else if (ModelUtils.isEmailSchema(p)) { + property.isEmail = true; + } else if (ModelUtils.isDateSchema(p)) { // date format + property.setIsString(false); // for backward compatibility with 2.x + property.isDate = true; + } else if (ModelUtils.isDateTimeSchema(p)) { // date-time format + property.setIsString(false); // for backward compatibility with 2.x + property.isDateTime = true; + } else if (ModelUtils.isDecimalSchema(p)) { // type: string, format: number + property.isDecimal = true; + property.setIsString(false); + } + property.pattern = toRegularExpression(p.getPattern()); + } + /** * Convert OAS Property object to Codegen Property object. * @@ -3352,89 +3464,6 @@ public class DefaultCodegen implements CodegenConfig { } } - String type = getSchemaType(p); - if (ModelUtils.isIntegerSchema(p)) { // integer type - property.isNumeric = Boolean.TRUE; - if (ModelUtils.isLongSchema(p)) { // int64/long format - property.isLong = Boolean.TRUE; - } else { - property.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int - if (ModelUtils.isShortSchema(p)) { // int32 - property.setIsShort(Boolean.TRUE); - } else { // unbounded integer - property.setIsUnboundedInteger(Boolean.TRUE); - } - } - } else if (ModelUtils.isBooleanSchema(p)) { // boolean type - property.isBoolean = true; - property.getter = toBooleanGetter(name); - } else if (ModelUtils.isDateSchema(p)) { // date format - property.isString = false; // for backward compatibility with 2.x - property.isDate = true; - - } else if (ModelUtils.isDateTimeSchema(p)) { // date-time format - property.isString = false; // for backward compatibility with 2.x - property.isDateTime = true; - } else if (ModelUtils.isDecimalSchema(p)) { // type: string, format: number - property.isDecimal = true; - } else if (ModelUtils.isStringSchema(p)) { - if (ModelUtils.isByteArraySchema(p)) { - property.isByteArray = true; - } else if (ModelUtils.isBinarySchema(p)) { - property.isBinary = true; - property.isFile = true; // file = binary in OAS3 - } else if (ModelUtils.isFileSchema(p)) { - property.isFile = true; - } else if (ModelUtils.isUUIDSchema(p)) { - // keep isString to true to make it backward compatible - property.isString = true; - property.isUuid = true; - } else if (ModelUtils.isURISchema(p)) { - property.isString = true; // for backward compatibility - property.isUri = true; - } else if (ModelUtils.isEmailSchema(p)) { - property.isString = true; - property.isEmail = true; - } else { - property.isString = true; - } - property.pattern = toRegularExpression(p.getPattern()); - - } else if (ModelUtils.isNumberSchema(p)) { - property.isNumeric = Boolean.TRUE; - if (ModelUtils.isFloatSchema(p)) { // float - property.isFloat = Boolean.TRUE; - } else if (ModelUtils.isDoubleSchema(p)) { // double - property.isDouble = Boolean.TRUE; - } else { // type is number and without format - property.isNumber = Boolean.TRUE; - } - - } else if (isFreeFormObject(p)) { - property.isFreeFormObject = true; - } else if (isAnyTypeSchema(p)) { - // The 'null' value is allowed when the OAS schema is 'any type'. - // See https://github.com/OAI/OpenAPI-Specification/issues/1389 - if (Boolean.FALSE.equals(p.getNullable())) { - LOGGER.warn("Schema '{}' is any type, which includes the 'null' value. 'nullable' cannot be set to 'false'", p.getName()); - } - property.isNullable = true; - property.isAnyType = true; - } else if (ModelUtils.isArraySchema(p)) { - // default to string if inner item is undefined - ArraySchema arraySchema = (ArraySchema) p; - Schema innerSchema = unaliasSchema(getSchemaItems(arraySchema), importMapping); - } else if (ModelUtils.isMapSchema(p)) { - Schema innerSchema = unaliasSchema(getAdditionalProperties(p), importMapping); - if (innerSchema == null) { - LOGGER.error("Undefined map inner type for `{}`. Default to String.", p.getName()); - innerSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to undefined type"); - p.setAdditionalProperties(innerSchema); - } - } else if (ModelUtils.isNullType(p)) { - property.isNull = true; - } - //Inline enum case: if (p.getEnum() != null && !p.getEnum().isEmpty()) { List _enum = p.getEnum(); @@ -3480,9 +3509,34 @@ public class DefaultCodegen implements CodegenConfig { property.datatypeWithEnum = property.dataType; } - if (ModelUtils.isArraySchema(p)) { + property.setTypeProperties(p); + if (ModelUtils.isIntegerSchema(p)) { // integer type + property.isNumeric = Boolean.TRUE; + if (ModelUtils.isLongSchema(p)) { // int64/long format + property.isLong = Boolean.TRUE; + } else { + property.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int + if (ModelUtils.isShortSchema(p)) { // int32 + property.setIsShort(Boolean.TRUE); + } + } + } else if (ModelUtils.isBooleanSchema(p)) { // boolean type + property.getter = toBooleanGetter(name); + } else if (ModelUtils.isFileSchema(p) && !ModelUtils.isStringSchema(p)) { + // swagger v2 only, type file + property.isFile = true; + } else if (ModelUtils.isStringSchema(p)) { + updatePropertyForString(property, p); + } else if (ModelUtils.isNumberSchema(p)) { + property.isNumeric = Boolean.TRUE; + if (ModelUtils.isFloatSchema(p)) { // float + property.isFloat = Boolean.TRUE; + } else if (ModelUtils.isDoubleSchema(p)) { // double + property.isDouble = Boolean.TRUE; + } + } else if (ModelUtils.isArraySchema(p)) { + // default to string if inner item is undefined property.isContainer = true; - property.isArray = true; if (ModelUtils.isSet(p)) { property.containerType = "set"; } else { @@ -3508,43 +3562,29 @@ public class DefaultCodegen implements CodegenConfig { Schema innerSchema = unaliasSchema(getSchemaItems(arraySchema), importMapping); CodegenProperty cp = fromProperty(itemName, innerSchema); updatePropertyForArray(property, cp); - } else if (ModelUtils.isMapSchema(p)) { - property.isContainer = true; - property.isMap = true; - property.containerType = "map"; - property.baseType = getSchemaType(p); - // TODO remove this hack in the future, code should use minProperties and maxProperties for object schemas - property.minItems = p.getMinProperties(); - property.maxItems = p.getMaxProperties(); - - // handle inner property - Schema innerSchema = unaliasSchema(getAdditionalProperties(p), importMapping); - if (innerSchema == null) { - LOGGER.error("Undefined map inner type for `{}`. Default to String.", p.getName()); - innerSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to undefined type"); - p.setAdditionalProperties(innerSchema); - } - CodegenProperty cp = fromProperty("inner", innerSchema); - updatePropertyForMap(property, cp); - } else if (isFreeFormObject(p)) { - property.isFreeFormObject = true; - property.baseType = getSchemaType(p); - if (languageSpecificPrimitives.contains(property.dataType)) { - property.isPrimitiveType = true; - } - } else if (isAnyTypeSchema(p)) { - property.isAnyType = true; - property.baseType = getSchemaType(p); - if (languageSpecificPrimitives.contains(property.dataType)) { - property.isPrimitiveType = true; - } - } else { // model - setNonArrayMapProperty(property, type); - Schema refOrCurrent = ModelUtils.getReferencedSchema(this.openAPI, p); - property.isModel = (ModelUtils.isComposedSchema(refOrCurrent) || ModelUtils.isObjectSchema(refOrCurrent)) && ModelUtils.isModel(refOrCurrent); + } else if (ModelUtils.isTypeObjectSchema(p)) { + updatePropertyForObject(property, p); + } else if (ModelUtils.isAnyType(p)) { + updatePropertyForAnyType(property, p); + } else if (!ModelUtils.isNullType(p)) { + // referenced model + ; + } + + Boolean isAnyTypeWithNothingElseSet = (ModelUtils.isAnyType(p) && + (p.getProperties() == null || p.getProperties().isEmpty()) && + !ModelUtils.isComposedSchema(p) && + p.getAdditionalProperties() == null && p.getNot() == null && p.getEnum() == null); + + if (!ModelUtils.isArraySchema(p) && !ModelUtils.isMapSchema(p) && !isFreeFormObject(p) && !isAnyTypeWithNothingElseSet) { + /** schemas that are not Array, not ModelUtils.isMapSchema, not isFreeFormObject, not AnyType with nothing else set + * so primitve schemas int, str, number, referenced schemas, AnyType schemas with properties, enums, or composition + */ + String type = getSchemaType(p); + setNonArrayMapProperty(property, type); + property.isModel = (ModelUtils.isComposedSchema(referencedSchema) || ModelUtils.isObjectSchema(referencedSchema)) && ModelUtils.isModel(referencedSchema); } - addVarsRequiredVarsAdditionalProps(p, property); LOGGER.debug("debugging from property return: {}", property); schemaCodegenPropertyCache.put(ns, property); return property; @@ -3603,6 +3643,7 @@ public class DefaultCodegen implements CodegenConfig { } else { property.isPrimitiveType = true; } + // TODO fix this, map should not be assigning properties to items property.items = innerProperty; property.mostInnerItems = getMostInnerItems(innerProperty); property.dataFormat = innerProperty.dataFormat; @@ -3635,7 +3676,7 @@ public class DefaultCodegen implements CodegenConfig { protected CodegenProperty getMostInnerItems(CodegenProperty property) { CodegenProperty currentProperty = property; while (currentProperty != null && (Boolean.TRUE.equals(currentProperty.isMap) - || Boolean.TRUE.equals(currentProperty.isArray))) { + || Boolean.TRUE.equals(currentProperty.isArray)) && currentProperty.items != null) { currentProperty = currentProperty.items; } return currentProperty; @@ -4179,12 +4220,6 @@ public class DefaultCodegen implements CodegenConfig { responseSchema = ModelUtils.getSchemaFromResponse(response); } r.schema = responseSchema; - if (responseSchema != null) { - ModelUtils.syncValidationProperties(responseSchema, r); - if (responseSchema.getPattern() != null) { - r.setPattern(toRegularExpression(responseSchema.getPattern())); - } - } r.message = escapeText(response.getDescription()); // TODO need to revise and test examples in responses @@ -4197,101 +4232,106 @@ public class DefaultCodegen implements CodegenConfig { addHeaders(response, r.headers); r.hasHeaders = !r.headers.isEmpty(); - if (r.schema != null) { - Map allSchemas = null; - CodegenProperty cp = fromProperty("response", responseSchema); - r.isNull = cp.isNull; + if (r.schema == null) { + r.primitiveType = true; + r.simpleType = true; + return r; + } - if (ModelUtils.isArraySchema(responseSchema)) { - ArraySchema as = (ArraySchema) responseSchema; - CodegenProperty items = fromProperty("response", getSchemaItems(as)); - r.setItems(items); - CodegenProperty innerCp = items; + ModelUtils.syncValidationProperties(responseSchema, r); + if (responseSchema.getPattern() != null) { + r.setPattern(toRegularExpression(responseSchema.getPattern())); + } - while (innerCp != null) { - r.baseType = innerCp.baseType; - innerCp = innerCp.items; - } - } else { - if (cp.complexType != null) { - if (cp.items != null) { - r.baseType = cp.items.complexType; - } else { - r.baseType = cp.complexType; - } - r.isModel = true; + CodegenProperty cp = fromProperty("response", responseSchema); + r.dataType = getTypeDeclaration(responseSchema); + + if (!ModelUtils.isArraySchema(responseSchema)) { + if (cp.complexType != null) { + if (cp.items != null) { + r.baseType = cp.items.complexType; } else { - r.baseType = cp.baseType; + r.baseType = cp.complexType; } + r.isModel = true; + } else { + r.baseType = cp.baseType; } + } - r.dataType = cp.dataType; - if (Boolean.TRUE.equals(cp.isString) && Boolean.TRUE.equals(cp.isEmail)) { + r.setTypeProperties(responseSchema); + if (ModelUtils.isArraySchema(responseSchema)) { + r.simpleType = false; + r.containerType = cp.containerType; + ArraySchema as = (ArraySchema) responseSchema; + CodegenProperty items = fromProperty("response", getSchemaItems(as)); + r.setItems(items); + CodegenProperty innerCp = items; + + while (innerCp != null) { + r.baseType = innerCp.baseType; + innerCp = innerCp.items; + } + } else if (ModelUtils.isFileSchema(responseSchema) && !ModelUtils.isStringSchema(responseSchema)) { + // swagger v2 only, type file + r.isFile = true; + } else if (ModelUtils.isStringSchema(responseSchema)) { + if (ModelUtils.isEmailSchema(responseSchema)) { r.isEmail = true; - } else if (Boolean.TRUE.equals(cp.isString) && Boolean.TRUE.equals(cp.isUuid)) { + } else if (ModelUtils.isUUIDSchema(responseSchema)) { r.isUuid = true; - } else if (Boolean.TRUE.equals(cp.isByteArray)) { + } else if (ModelUtils.isByteArraySchema(responseSchema)) { r.isByteArray = true; - } else if (Boolean.TRUE.equals(cp.isString)) { - r.isString = true; - } else if (Boolean.TRUE.equals(cp.isBoolean)) { - r.isBoolean = true; - } else if (Boolean.TRUE.equals(cp.isLong)) { - r.isLong = true; - r.isNumeric = true; - } else if (Boolean.TRUE.equals(cp.isInteger)) { - r.isInteger = true; - r.isNumeric = true; - if (Boolean.TRUE.equals(cp.isShort)) { - r.isShort = true; - } else if (Boolean.TRUE.equals(cp.isUnboundedInteger)) { - r.isUnboundedInteger = true; - } - } else if (Boolean.TRUE.equals(cp.isNumber)) { - r.isNumber = true; - r.isNumeric = true; - } else if (Boolean.TRUE.equals(cp.isDouble)) { - r.isDouble = true; - r.isNumeric = true; - } else if (Boolean.TRUE.equals(cp.isFloat)) { - r.isFloat = true; - r.isNumeric = true; - } else if (Boolean.TRUE.equals(cp.isDecimal)) { - r.isDecimal = true; - r.isNumeric = true; - } else if (Boolean.TRUE.equals(cp.isBinary)) { + } else if (ModelUtils.isBinarySchema(responseSchema)) { r.isFile = true; // file = binary in OAS3 r.isBinary = true; - } else if (Boolean.TRUE.equals(cp.isFile)) { - r.isFile = true; - } else if (Boolean.TRUE.equals(cp.isDate)) { + } else if (ModelUtils.isDateSchema(responseSchema)) { + r.setIsString(false); // for backward compatibility with 2.x r.isDate = true; - } else if (Boolean.TRUE.equals(cp.isDateTime)) { + } else if (ModelUtils.isDateTimeSchema(responseSchema)) { + r.setIsString(false); // for backward compatibility with 2.x r.isDateTime = true; - } else if (Boolean.TRUE.equals(cp.isFreeFormObject)) { + } else if (ModelUtils.isDecimalSchema(responseSchema)) { // type: string, format: number + r.isDecimal = true; + r.setIsString(false); + r.isNumeric = true; + } + } else if (ModelUtils.isIntegerSchema(responseSchema)) { // integer type + r.isNumeric = Boolean.TRUE; + if (ModelUtils.isLongSchema(responseSchema)) { // int64/long format + r.isLong = Boolean.TRUE; + } else { + r.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int + if (ModelUtils.isShortSchema(responseSchema)) { // int32 + r.setIsShort(Boolean.TRUE); + } + } + } else if (ModelUtils.isNumberSchema(responseSchema)) { + r.isNumeric = Boolean.TRUE; + if (ModelUtils.isFloatSchema(responseSchema)) { // float + r.isFloat = Boolean.TRUE; + } else if (ModelUtils.isDoubleSchema(responseSchema)) { // double + r.isDouble = Boolean.TRUE; + } + } else if (ModelUtils.isTypeObjectSchema(responseSchema)) { + if (ModelUtils.isFreeFormObject(openAPI, responseSchema)) { r.isFreeFormObject = true; - } else if (Boolean.TRUE.equals(cp.isAnyType)) { - r.isAnyType = true; - } else { - LOGGER.debug("Property type is not primitive: {}", cp.dataType); } - - if (cp.isContainer) { - r.simpleType = false; - r.containerType = cp.containerType; - r.isMap = "map".equals(cp.containerType); - r.isArray = "list".equalsIgnoreCase(cp.containerType) || - "array".equalsIgnoreCase(cp.containerType) || - "set".equalsIgnoreCase(cp.containerType); - } else { - r.simpleType = true; - } - - r.primitiveType = (r.baseType == null || languageSpecificPrimitives().contains(r.baseType)); - + r.simpleType = false; + r.containerType = cp.containerType; addVarsRequiredVarsAdditionalProps(responseSchema, r); + } else if (ModelUtils.isAnyType(responseSchema)) { + addVarsRequiredVarsAdditionalProps(responseSchema, r); + } else if (!ModelUtils.isBooleanSchema(responseSchema)){ + // referenced schemas + LOGGER.debug("Property type is not primitive: {}", cp.dataType); } + if (!r.isMap && !r.isArray) { + r.simpleType = true; + } + r.primitiveType = (r.baseType == null || languageSpecificPrimitives().contains(r.baseType)); + if (r.baseType == null) { r.isMap = false; r.isArray = false; @@ -4366,6 +4406,68 @@ public class DefaultCodegen implements CodegenConfig { return c; } + private void finishUpdatingParameter(CodegenParameter codegenParameter, Parameter parameter) { + // default to UNKNOWN_PARAMETER_NAME if paramName is null + if (codegenParameter.paramName == null) { + LOGGER.warn("Parameter name not defined properly. Default to UNKNOWN_PARAMETER_NAME"); + codegenParameter.paramName = "UNKNOWN_PARAMETER_NAME"; + } + + // set the parameter example value + // should be overridden by lang codegen + setParameterExampleValue(codegenParameter, parameter); + + postProcessParameter(codegenParameter); + LOGGER.debug("debugging codegenParameter return: {}", codegenParameter); + } + + + private void updateParameterForMap(CodegenParameter codegenParameter, Schema parameterSchema, Set imports) { + CodegenProperty codegenProperty = fromProperty("inner", getAdditionalProperties(parameterSchema)); + codegenParameter.items = codegenProperty; + codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; + codegenParameter.baseType = codegenProperty.dataType; + codegenParameter.isContainer = true; + codegenParameter.isMap = true; + + // recursively add import + while (codegenProperty != null) { + imports.add(codegenProperty.baseType); + codegenProperty = codegenProperty.items; + } + } + + protected void updateParameterForString(CodegenParameter codegenParameter, Schema parameterSchema){ + if (ModelUtils.isEmailSchema(parameterSchema)) { + codegenParameter.isEmail = true; + } else if (ModelUtils.isUUIDSchema(parameterSchema)) { + codegenParameter.isUuid = true; + } else if (ModelUtils.isByteArraySchema(parameterSchema)) { + codegenParameter.setIsString(false); + codegenParameter.isByteArray = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isBinarySchema(parameterSchema)) { + codegenParameter.isBinary = true; + codegenParameter.isFile = true; // file = binary in OAS3 + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateSchema(parameterSchema)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDate = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateTimeSchema(parameterSchema)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDateTime = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDecimalSchema(parameterSchema)) { // type: string, format: number + codegenParameter.setIsString(false); + codegenParameter.isDecimal = true; + codegenParameter.isPrimitiveType = true; + } + if (Boolean.TRUE.equals(codegenParameter.isString)) { + codegenParameter.isPrimitiveType = true; + } + } + /** * Convert OAS Parameter object to Codegen Parameter object * @@ -4411,165 +4513,6 @@ public class DefaultCodegen implements CodegenConfig { parameterSchema = null; } - if (parameterSchema != null) { - parameterSchema = unaliasSchema(parameterSchema, Collections.emptyMap()); - if (parameterSchema == null) { - LOGGER.warn("warning! Schema not found for parameter \" {} \", using String", parameter.getName()); - parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition."); - } - ModelUtils.syncValidationProperties(parameterSchema, codegenParameter); - - if (Boolean.TRUE.equals(parameterSchema.getNullable())) { // use nullable defined in the spec - codegenParameter.isNullable = true; - } - - // set default value - codegenParameter.defaultValue = toDefaultParameterValue(parameterSchema); - - if (parameter.getStyle() != null) { - codegenParameter.style = parameter.getStyle().toString(); - codegenParameter.isDeepObject = Parameter.StyleEnum.DEEPOBJECT == parameter.getStyle(); - } - - // the default value is false - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#user-content-parameterexplode - codegenParameter.isExplode = parameter.getExplode() == null ? false : parameter.getExplode(); - - // TODO revise collectionFormat, default collection format in OAS 3 appears to multi at least for query parameters - // https://swagger.io/docs/specification/serialization/ - String collectionFormat = null; - if (ModelUtils.isArraySchema(parameterSchema)) { // for array parameter - final ArraySchema arraySchema = (ArraySchema) parameterSchema; - Schema inner = getSchemaItems(arraySchema); - - collectionFormat = getCollectionFormat(parameter); - // default to csv: - collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat; - CodegenProperty codegenProperty = fromProperty("inner", inner); - codegenParameter.items = codegenProperty; - codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; - codegenParameter.baseType = codegenProperty.dataType; - codegenParameter.isContainer = true; - codegenParameter.isArray = true; - - // recursively add import - while (codegenProperty != null) { - imports.add(codegenProperty.baseType); - codegenProperty = codegenProperty.items; - } - - } else if (ModelUtils.isMapSchema(parameterSchema)) { // for map parameter - CodegenProperty codegenProperty = fromProperty("inner", getAdditionalProperties(parameterSchema)); - codegenParameter.items = codegenProperty; - codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; - codegenParameter.baseType = codegenProperty.dataType; - codegenParameter.isContainer = true; - codegenParameter.isMap = true; - - // recursively add import - while (codegenProperty != null) { - imports.add(codegenProperty.baseType); - codegenProperty = codegenProperty.items; - } - } else if (ModelUtils.isNullType(parameterSchema)) { - codegenParameter.isNull = true; - } -/* TODO revise the logic below - } else { - Map args = new HashMap(); - String format = qp.getFormat(); - args.put(PropertyId.ENUM, qp.getEnum()); - property = PropertyBuilder.build(type, format, args); - } -*/ - - CodegenProperty codegenProperty = fromProperty(parameter.getName(), parameterSchema); - // TODO revise below which seems not working - //if (parameterSchema.getRequired() != null && !parameterSchema.getRequired().isEmpty() && parameterSchema.getRequired().contains(codegenProperty.baseName)) { - codegenProperty.required = Boolean.TRUE.equals(parameter.getRequired()) ? true : false; - //} - //codegenProperty.required = true; - - // set boolean flag (e.g. isString) - setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty); - - String parameterDataType = this.getParameterDataType(parameter, parameterSchema); - if (parameterDataType != null) { - codegenParameter.dataType = parameterDataType; - } else { - codegenParameter.dataType = codegenProperty.dataType; - } - if (ModelUtils.isObjectSchema(parameterSchema)) { - codegenProperty.complexType = codegenParameter.dataType; - } - if (ModelUtils.isSet(parameterSchema)) { - imports.add(codegenProperty.baseType); - } - codegenParameter.dataFormat = codegenProperty.dataFormat; - codegenParameter.required = codegenProperty.required; - - if (codegenProperty.isEnum) { - codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum; - codegenParameter.enumName = codegenProperty.enumName; - } - - // enum - updateCodegenPropertyEnum(codegenProperty); - codegenParameter.isEnum = codegenProperty.isEnum; - codegenParameter._enum = codegenProperty._enum; - codegenParameter.allowableValues = codegenProperty.allowableValues; - - if (codegenProperty.items != null && codegenProperty.items.isEnum) { - codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum; - codegenParameter.enumName = codegenProperty.enumName; - codegenParameter.items = codegenProperty.items; - codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; - } - - codegenParameter.collectionFormat = collectionFormat; - if ("multi".equals(collectionFormat)) { - codegenParameter.isCollectionFormatMulti = true; - } - codegenParameter.paramName = toParamName(parameter.getName()); - - // import - if (codegenProperty.complexType != null) { - imports.add(codegenProperty.complexType); - } - - // validation - // handle maximum, minimum properly for int/long by removing the trailing ".0" - if (ModelUtils.isIntegerSchema(parameterSchema)) { - codegenParameter.maximum = parameterSchema.getMaximum() == null ? null : String.valueOf(parameterSchema.getMaximum().longValue()); - codegenParameter.minimum = parameterSchema.getMinimum() == null ? null : String.valueOf(parameterSchema.getMinimum().longValue()); - } else { - codegenParameter.maximum = parameterSchema.getMaximum() == null ? null : String.valueOf(parameterSchema.getMaximum()); - codegenParameter.minimum = parameterSchema.getMinimum() == null ? null : String.valueOf(parameterSchema.getMinimum()); - } - - codegenParameter.exclusiveMaximum = parameterSchema.getExclusiveMaximum() == null ? false : parameterSchema.getExclusiveMaximum(); - codegenParameter.exclusiveMinimum = parameterSchema.getExclusiveMinimum() == null ? false : parameterSchema.getExclusiveMinimum(); - codegenParameter.maxLength = parameterSchema.getMaxLength(); - codegenParameter.minLength = parameterSchema.getMinLength(); - codegenParameter.pattern = toRegularExpression(parameterSchema.getPattern()); - codegenParameter.maxItems = parameterSchema.getMaxItems(); - codegenParameter.minItems = parameterSchema.getMinItems(); - codegenParameter.uniqueItems = parameterSchema.getUniqueItems() == null ? false : parameterSchema.getUniqueItems(); - codegenParameter.multipleOf = parameterSchema.getMultipleOf(); - - // exclusive* are noop without corresponding min/max - if (codegenParameter.maximum != null || codegenParameter.minimum != null || - codegenParameter.maxLength != null || codegenParameter.minLength != null || - codegenParameter.maxItems != null || codegenParameter.minItems != null || - codegenParameter.pattern != null || codegenParameter.multipleOf != null) { - codegenParameter.hasValidation = true; - } - addVarsRequiredVarsAdditionalProps(parameterSchema, codegenParameter); - - } else { - LOGGER.error("Not handling {} as Body Parameter at the moment", parameter); - } - if (parameter instanceof QueryParameter || "query".equalsIgnoreCase(parameter.getIn())) { codegenParameter.isQueryParam = true; codegenParameter.isAllowEmptyValue = parameter.getAllowEmptyValue() != null && parameter.getAllowEmptyValue(); @@ -4584,12 +4527,162 @@ public class DefaultCodegen implements CodegenConfig { LOGGER.warn("Unknown parameter type: {}", parameter.getName()); } - // default to UNKNOWN_PARAMETER_NAME if paramName is null - if (codegenParameter.paramName == null) { - LOGGER.warn("Parameter name not defined properly. Default to UNKNOWN_PARAMETER_NAME"); - codegenParameter.paramName = "UNKNOWN_PARAMETER_NAME"; + if (parameterSchema == null) { + LOGGER.error("Not handling {} as Body Parameter at the moment", parameter); + finishUpdatingParameter(codegenParameter, parameter); + return codegenParameter; } + parameterSchema = unaliasSchema(parameterSchema, Collections.emptyMap()); + if (parameterSchema == null) { + LOGGER.warn("warning! Schema not found for parameter \" {} \", using String", parameter.getName()); + parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition."); + finishUpdatingParameter(codegenParameter, parameter); + return codegenParameter; + } + ModelUtils.syncValidationProperties(parameterSchema, codegenParameter); + codegenParameter.setTypeProperties(parameterSchema); + + if (Boolean.TRUE.equals(parameterSchema.getNullable())) { // use nullable defined in the spec + codegenParameter.isNullable = true; + } + + // set default value + codegenParameter.defaultValue = toDefaultParameterValue(parameterSchema); + + if (parameter.getStyle() != null) { + codegenParameter.style = parameter.getStyle().toString(); + codegenParameter.isDeepObject = Parameter.StyleEnum.DEEPOBJECT == parameter.getStyle(); + } + + // the default value is false + // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#user-content-parameterexplode + codegenParameter.isExplode = parameter.getExplode() == null ? false : parameter.getExplode(); + + // TODO revise collectionFormat, default collection format in OAS 3 appears to multi at least for query parameters + // https://swagger.io/docs/specification/serialization/ + String collectionFormat = null; + + if (ModelUtils.isFileSchema(parameterSchema) && !ModelUtils.isStringSchema(parameterSchema)) { + // swagger v2 only, type file + codegenParameter.isFile = true; + } else if (ModelUtils.isStringSchema(parameterSchema)) { + updateParameterForString(codegenParameter, parameterSchema); + } else if (ModelUtils.isBooleanSchema(parameterSchema)) { + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isNumberSchema(parameterSchema)) { + codegenParameter.isPrimitiveType = true; + if (ModelUtils.isFloatSchema(parameterSchema)) { // float + codegenParameter.isFloat = true; + } else if (ModelUtils.isDoubleSchema(parameterSchema)) { // double + codegenParameter.isDouble = true; + } + } else if (ModelUtils.isIntegerSchema(parameterSchema)) { // integer type + codegenParameter.isPrimitiveType = true; + if (ModelUtils.isLongSchema(parameterSchema)) { // int64/long format + codegenParameter.isLong = true; + } else { + codegenParameter.isInteger = true; + if (ModelUtils.isShortSchema(parameterSchema)) { // int32/short format + codegenParameter.isShort = true; + } else { // unbounded integer + ; + } + } + } else if (ModelUtils.isTypeObjectSchema(parameterSchema)) { + if (ModelUtils.isMapSchema(parameterSchema)) { // for map parameter + updateParameterForMap(codegenParameter, parameterSchema, imports); + } + if (ModelUtils.isFreeFormObject(openAPI, parameterSchema)) { + codegenParameter.isFreeFormObject = true; + } + addVarsRequiredVarsAdditionalProps(parameterSchema, codegenParameter); + } else if (ModelUtils.isNullType(parameterSchema)) { + ; + } else if (ModelUtils.isAnyType(parameterSchema)) { + // any schema with no type set, composed schemas often do this + if (ModelUtils.isMapSchema(parameterSchema)) { // for map parameter + updateParameterForMap(codegenParameter, parameterSchema, imports); + } + addVarsRequiredVarsAdditionalProps(parameterSchema, codegenParameter); + } else if (ModelUtils.isArraySchema(parameterSchema)) { + final ArraySchema arraySchema = (ArraySchema) parameterSchema; + Schema inner = getSchemaItems(arraySchema); + + collectionFormat = getCollectionFormat(parameter); + // default to csv: + collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat; + CodegenProperty itemsProperty = fromProperty("inner", inner); + codegenParameter.items = itemsProperty; + codegenParameter.mostInnerItems = itemsProperty.mostInnerItems; + codegenParameter.baseType = itemsProperty.dataType; + codegenParameter.isContainer = true; + + // recursively add import + while (itemsProperty != null) { + imports.add(itemsProperty.baseType); + itemsProperty = itemsProperty.items; + } + } else { + // referenced schemas + ; + } + + CodegenProperty codegenProperty = fromProperty(parameter.getName(), parameterSchema); + if (Boolean.TRUE.equals(codegenProperty.isModel)) { + codegenParameter.isModel = true; + } + // TODO revise below which seems not working + //if (parameterSchema.getRequired() != null && !parameterSchema.getRequired().isEmpty() && parameterSchema.getRequired().contains(codegenProperty.baseName)) { + codegenProperty.required = Boolean.TRUE.equals(parameter.getRequired()) ? true : false; + //} + //codegenProperty.required = true; + + String parameterDataType = this.getParameterDataType(parameter, parameterSchema); + if (parameterDataType != null) { + codegenParameter.dataType = parameterDataType; + } else { + codegenParameter.dataType = codegenProperty.dataType; + } + if (ModelUtils.isObjectSchema(parameterSchema)) { + codegenProperty.complexType = codegenParameter.dataType; + } + if (ModelUtils.isSet(parameterSchema)) { + imports.add(codegenProperty.baseType); + } + codegenParameter.dataFormat = codegenProperty.dataFormat; + codegenParameter.required = codegenProperty.required; + + if (codegenProperty.isEnum) { + codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum; + codegenParameter.enumName = codegenProperty.enumName; + } + + // enum + updateCodegenPropertyEnum(codegenProperty); + codegenParameter.isEnum = codegenProperty.isEnum; + codegenParameter._enum = codegenProperty._enum; + codegenParameter.allowableValues = codegenProperty.allowableValues; + + if (codegenProperty.items != null && codegenProperty.items.isEnum) { + codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum; + codegenParameter.enumName = codegenProperty.enumName; + codegenParameter.items = codegenProperty.items; + codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; + } + + codegenParameter.collectionFormat = collectionFormat; + if ("multi".equals(collectionFormat)) { + codegenParameter.isCollectionFormatMulti = true; + } + codegenParameter.paramName = toParamName(parameter.getName()); + + // import + if (codegenProperty.complexType != null) { + imports.add(codegenProperty.complexType); + } + codegenParameter.pattern = toRegularExpression(parameterSchema.getPattern()); + if (codegenParameter.isQueryParam && codegenParameter.isDeepObject) { Schema schema = ModelUtils.getSchema(openAPI, codegenParameter.dataType); codegenParameter.items = fromProperty(codegenParameter.paramName, schema); @@ -4612,12 +4705,7 @@ public class DefaultCodegen implements CodegenConfig { } } - // set the parameter example value - // should be overridden by lang codegen - setParameterExampleValue(codegenParameter, parameter); - - postProcessParameter(codegenParameter); - LOGGER.debug("debugging codegenParameter return: {}", codegenParameter); + finishUpdatingParameter(codegenParameter, parameter); return codegenParameter; } @@ -4978,7 +5066,7 @@ public class DefaultCodegen implements CodegenConfig { * @param properties model properties (schemas) * @return model properties with direct reference to schemas */ - private Map unaliasPropertySchema(Map properties) { + protected Map unaliasPropertySchema(Map properties) { if (properties != null) { for (String key : properties.keySet()) { properties.put(key, unaliasSchema(properties.get(key), importMapping())); @@ -4989,7 +5077,7 @@ public class DefaultCodegen implements CodegenConfig { return properties; } - private void addVars(CodegenModel m, Map properties, List required, + protected void addVars(CodegenModel m, Map properties, List required, Map allProperties, List allRequired) { m.hasRequired = false; @@ -5581,6 +5669,9 @@ public class DefaultCodegen implements CodegenConfig { /** * Set CodegenParameter boolean flag using CodegenProperty. + * NOTE: This is deprecated and can be removed in 6.0.0 + * This logic has been folded into the original call sites and long term will be moved into + * IJsonSchemaValidationProperties.setTypeProperties and overrides like updateModelForObject * * @param parameter Codegen Parameter * @param property Codegen property @@ -6020,6 +6111,10 @@ public class DefaultCodegen implements CodegenConfig { schema = ModelUtils.getReferencedSchema(this.openAPI, schema); List allRequired = new ArrayList(); Map properties = new LinkedHashMap<>(); + // this traverses a composed schema and extracts all properties in each schema into properties + // TODO in the future have this return one codegenParameter of type object or composed which includes all definition + // that will be needed for complex composition use cases + // https://github.com/OpenAPITools/openapi-generator/issues/10415 addProperties(properties, allRequired, schema); if (!properties.isEmpty()) { @@ -6027,48 +6122,13 @@ public class DefaultCodegen implements CodegenConfig { CodegenParameter codegenParameter; // key => property name // value => property schema - Schema s = entry.getValue(); - // array of schema - if (ModelUtils.isArraySchema(s)) { - final ArraySchema arraySchema = (ArraySchema) s; - Schema inner = getSchemaItems(arraySchema); - - codegenParameter = fromFormProperty(entry.getKey(), inner, imports); - CodegenProperty codegenProperty = fromProperty("inner", inner); - codegenParameter.items = codegenProperty; - codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; - codegenParameter.baseType = codegenProperty.dataType; - codegenParameter.isPrimitiveType = false; - codegenParameter.isContainer = true; - codegenParameter.isArray = true; - codegenParameter.description = escapeText(s.getDescription()); - codegenParameter.dataType = getTypeDeclaration(arraySchema); - if (codegenParameter.baseType != null && codegenParameter.enumName != null) { - codegenParameter.datatypeWithEnum = codegenParameter.dataType.replace(codegenParameter.baseType, codegenParameter.enumName); - } else { - LOGGER.warn("Could not compute datatypeWithEnum from {}, {}", codegenParameter.baseType, codegenParameter.enumName); - } - //TODO fix collectionFormat for form parameters - //collectionFormat = getCollectionFormat(s); - String collectionFormat = getCollectionFormat(codegenParameter); - // default to csv: - codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat; - - // set nullable - setParameterNullable(codegenParameter, codegenProperty); - - // recursively add import - while (codegenProperty != null) { - imports.add(codegenProperty.baseType); - codegenProperty = codegenProperty.items; - } - - } else if (ModelUtils.isMapSchema(s)) { + String propertyName = entry.getKey(); + Schema propertySchema = entry.getValue(); + if (ModelUtils.isMapSchema(propertySchema)) { LOGGER.error("Map of form parameters not supported. Please report the issue to https://github.com/openapitools/openapi-generator if you need help."); continue; - } else { - codegenParameter = fromFormProperty(entry.getKey(), entry.getValue(), imports); } + codegenParameter = fromFormProperty(propertyName, propertySchema, imports); // Set 'required' flag defined in the schema element if (!codegenParameter.required && schema.getRequired() != null) { @@ -6088,18 +6148,135 @@ public class DefaultCodegen implements CodegenConfig { LOGGER.debug("Debugging fromFormProperty {}: {}", name, propertySchema); CodegenProperty codegenProperty = fromProperty(name, propertySchema); - ModelUtils.syncValidationProperties(propertySchema, codegenProperty); + Schema ps = unaliasSchema(propertySchema, importMapping); + ModelUtils.syncValidationProperties(ps, codegenParameter); + codegenParameter.setTypeProperties(ps); + if (ps.getPattern() != null) { + codegenParameter.pattern = toRegularExpression(ps.getPattern()); + } - codegenParameter.isFormParam = Boolean.TRUE; - codegenParameter.baseName = codegenProperty.baseName; - codegenParameter.paramName = toParamName((codegenParameter.baseName)); codegenParameter.baseType = codegenProperty.baseType; codegenParameter.dataType = codegenProperty.dataType; + codegenParameter.defaultValue = codegenProperty.getDefaultValue(); + codegenParameter.baseName = codegenProperty.baseName; + codegenParameter.paramName = toParamName(codegenParameter.baseName); codegenParameter.dataFormat = codegenProperty.dataFormat; + // non-array/map + updateCodegenPropertyEnum(codegenProperty); + codegenParameter.isEnum = codegenProperty.isEnum; + codegenParameter._enum = codegenProperty._enum; + codegenParameter.allowableValues = codegenProperty.allowableValues; + + if (ModelUtils.isFileSchema(ps) && !ModelUtils.isStringSchema(ps)) { + // swagger v2 only, type file + codegenParameter.isFile = true; + } else if (ModelUtils.isStringSchema(ps)) { + if (ModelUtils.isEmailSchema(ps)) { + codegenParameter.isEmail = true; + } else if (ModelUtils.isUUIDSchema(ps)) { + codegenParameter.isUuid = true; + } else if (ModelUtils.isByteArraySchema(ps)) { + codegenParameter.setIsString(false); + codegenParameter.isByteArray = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isBinarySchema(ps)) { + codegenParameter.isBinary = true; + codegenParameter.isFile = true; // file = binary in OAS3 + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateSchema(ps)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDate = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateTimeSchema(ps)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDateTime = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDecimalSchema(ps)) { // type: string, format: number + codegenParameter.setIsString(false); + codegenParameter.isDecimal = true; + codegenParameter.isPrimitiveType = true; + } + if (Boolean.TRUE.equals(codegenParameter.isString)) { + codegenParameter.isPrimitiveType = true; + } + } else if (ModelUtils.isBooleanSchema(ps)) { + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isNumberSchema(ps)) { + codegenParameter.isPrimitiveType = true; + if (ModelUtils.isFloatSchema(ps)) { // float + codegenParameter.isFloat = true; + } else if (ModelUtils.isDoubleSchema(ps)) { // double + codegenParameter.isDouble = true; + } + } else if (ModelUtils.isIntegerSchema(ps)) { // integer type + codegenParameter.isPrimitiveType = true; + if (ModelUtils.isLongSchema(ps)) { // int64/long format + codegenParameter.isLong = true; + } else { + codegenParameter.isInteger = true; + if (ModelUtils.isShortSchema(ps)) { // int32/short format + codegenParameter.isShort = true; + } else { // unbounded integer + ; + } + } + } else if (ModelUtils.isTypeObjectSchema(ps)) { + if (ModelUtils.isFreeFormObject(openAPI, ps)) { + codegenParameter.isFreeFormObject = true; + } + } else if (ModelUtils.isNullType(ps)) { + ; + } else if (ModelUtils.isAnyType(ps)) { + // any schema with no type set, composed schemas often do this + ; + } else if (ModelUtils.isArraySchema(ps)) { + Schema inner = getSchemaItems((ArraySchema) ps); + CodegenProperty arrayInnerProperty = fromProperty("inner", inner); + codegenParameter.items = arrayInnerProperty; + codegenParameter.mostInnerItems = arrayInnerProperty.mostInnerItems; + codegenParameter.isPrimitiveType = false; + codegenParameter.isContainer = true; + // hoist items data into the array property + // TODO this hoisting code is generator specific and should be isolated into updateFormPropertyForArray + codegenParameter.baseType = arrayInnerProperty.dataType; + codegenParameter.defaultValue = arrayInnerProperty.getDefaultValue(); + if (codegenParameter.items.isFile) { + codegenParameter.isFile = true; + codegenParameter.dataFormat = codegenParameter.items.dataFormat; + } + if (arrayInnerProperty._enum != null) { + codegenParameter._enum = arrayInnerProperty._enum; + } + if (arrayInnerProperty.baseType != null && arrayInnerProperty.enumName != null) { + codegenParameter.datatypeWithEnum = codegenParameter.dataType.replace(arrayInnerProperty.baseType, arrayInnerProperty.enumName); + } else { + LOGGER.warn("Could not compute datatypeWithEnum from {}, {}", arrayInnerProperty.baseType, arrayInnerProperty.enumName); + } + // end of hoisting + //TODO fix collectionFormat for form parameters + //collectionFormat = getCollectionFormat(s); + String collectionFormat = getCollectionFormat(codegenParameter); + // default to csv: + codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat; + + // recursively add import + while (arrayInnerProperty != null) { + imports.add(arrayInnerProperty.baseType); + arrayInnerProperty = arrayInnerProperty.items; + } + } else { + // referenced schemas + ; + } + + if (Boolean.TRUE.equals(codegenProperty.isModel)) { + codegenParameter.isModel = true; + } + + codegenParameter.isFormParam = Boolean.TRUE; codegenParameter.description = escapeText(codegenProperty.description); codegenParameter.unescapedDescription = codegenProperty.getDescription(); codegenParameter.jsonSchema = Json.pretty(propertySchema); - codegenParameter.defaultValue = codegenProperty.getDefaultValue(); if (codegenProperty.getVendorExtensions() != null && !codegenProperty.getVendorExtensions().isEmpty()) { codegenParameter.vendorExtensions = codegenProperty.getVendorExtensions(); @@ -6108,56 +6285,16 @@ public class DefaultCodegen implements CodegenConfig { codegenParameter.required = Boolean.TRUE; } - // non-array/map - updateCodegenPropertyEnum(codegenProperty); - codegenParameter.isEnum = codegenProperty.isEnum; - codegenParameter._enum = codegenProperty._enum; - codegenParameter.allowableValues = codegenProperty.allowableValues; - if (codegenProperty.isEnum) { codegenParameter.datatypeWithEnum = codegenProperty.datatypeWithEnum; codegenParameter.enumName = codegenProperty.enumName; } - - if (codegenProperty.items != null && codegenProperty.items.isEnum) { - codegenParameter.items = codegenProperty.items; - codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; - } - + // import if (codegenProperty.complexType != null) { imports.add(codegenProperty.complexType); } - // validation - // handle maximum, minimum properly for int/long by removing the trailing ".0" - if (ModelUtils.isIntegerSchema(propertySchema)) { - codegenParameter.maximum = propertySchema.getMaximum() == null ? null : String.valueOf(propertySchema.getMaximum().longValue()); - codegenParameter.minimum = propertySchema.getMinimum() == null ? null : String.valueOf(propertySchema.getMinimum().longValue()); - } else { - codegenParameter.maximum = propertySchema.getMaximum() == null ? null : String.valueOf(propertySchema.getMaximum()); - codegenParameter.minimum = propertySchema.getMinimum() == null ? null : String.valueOf(propertySchema.getMinimum()); - } - - codegenParameter.exclusiveMaximum = propertySchema.getExclusiveMaximum() == null ? false : propertySchema.getExclusiveMaximum(); - codegenParameter.exclusiveMinimum = propertySchema.getExclusiveMinimum() == null ? false : propertySchema.getExclusiveMinimum(); - codegenParameter.maxLength = propertySchema.getMaxLength(); - codegenParameter.minLength = propertySchema.getMinLength(); - codegenParameter.pattern = toRegularExpression(propertySchema.getPattern()); - codegenParameter.maxItems = propertySchema.getMaxItems(); - codegenParameter.minItems = propertySchema.getMinItems(); - codegenParameter.uniqueItems = propertySchema.getUniqueItems() == null ? false : propertySchema.getUniqueItems(); - codegenParameter.multipleOf = propertySchema.getMultipleOf(); - - // exclusive* are noop without corresponding min/max - if (codegenParameter.maximum != null || codegenParameter.minimum != null || - codegenParameter.maxLength != null || codegenParameter.minLength != null || - codegenParameter.maxItems != null || codegenParameter.minItems != null || - codegenParameter.pattern != null || codegenParameter.multipleOf != null) { - codegenParameter.hasValidation = true; - } - - setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty); setParameterExampleValue(codegenParameter); // set nullable setParameterNullable(codegenParameter, codegenProperty); @@ -6240,12 +6377,183 @@ public class DefaultCodegen implements CodegenConfig { } } - setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty); // set nullable setParameterNullable(codegenParameter, codegenProperty); } } + protected void updateRequestBodyForMap(CodegenParameter codegenParameter, Schema schema, String name, Set imports, String bodyParameterName) { + if (ModelUtils.isGenerateAliasAsModel(schema) && StringUtils.isNotBlank(name)) { + this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, true); + } else { + Schema inner = getAdditionalProperties(schema); + if (inner == null) { + LOGGER.error("No inner type supplied for map parameter `{}`. Default to type:string", schema.getName()); + inner = new StringSchema().description("//TODO automatically added by openapi-generator"); + schema.setAdditionalProperties(inner); + } + CodegenProperty codegenProperty = fromProperty("property", schema); + + imports.add(codegenProperty.baseType); + + CodegenProperty innerCp = codegenProperty; + while (innerCp != null) { + if (innerCp.complexType != null) { + imports.add(innerCp.complexType); + } + innerCp = innerCp.items; + } + + if (StringUtils.isEmpty(bodyParameterName)) { + codegenParameter.baseName = "request_body"; + } else { + codegenParameter.baseName = bodyParameterName; + } + codegenParameter.paramName = toParamName(codegenParameter.baseName); + codegenParameter.items = codegenProperty.items; + codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; + codegenParameter.dataType = getTypeDeclaration(schema); + codegenParameter.baseType = getSchemaType(inner); + codegenParameter.isContainer = Boolean.TRUE; + codegenParameter.isMap = Boolean.TRUE; + codegenParameter.isNullable = codegenProperty.isNullable; + + // set nullable + setParameterNullable(codegenParameter, codegenProperty); + } + } + + protected void updateRequestBodyForPrimitiveType(CodegenParameter codegenParameter, Schema schema, String bodyParameterName, Set imports) { + CodegenProperty codegenProperty = fromProperty("PRIMITIVE_REQUEST_BODY", schema); + if (codegenProperty != null) { + if (StringUtils.isEmpty(bodyParameterName)) { + codegenParameter.baseName = "body"; // default to body + } else { + codegenParameter.baseName = bodyParameterName; + } + codegenParameter.isPrimitiveType = true; + codegenParameter.baseType = codegenProperty.baseType; + codegenParameter.dataType = codegenProperty.dataType; + codegenParameter.description = codegenProperty.description; + codegenParameter.paramName = toParamName(codegenParameter.baseName); + codegenParameter.pattern = codegenProperty.pattern; + codegenParameter.isNullable = codegenProperty.isNullable; + + if (codegenProperty.complexType != null) { + imports.add(codegenProperty.complexType); + } + + } + // set nullable + setParameterNullable(codegenParameter, codegenProperty); + } + + protected void updateRequestBodyForObject(CodegenParameter codegenParameter, Schema schema, String name, Set imports, String bodyParameterName) { + if (ModelUtils.isMapSchema(schema)) { + // Schema with additionalproperties: true (including composed schemas with additionalproperties: true) + updateRequestBodyForMap(codegenParameter, schema, name, imports, bodyParameterName); + } else if (isFreeFormObject(schema)) { + // non-composed object type with no properties + additionalProperties + // additionalProperties must be null, ObjectSchema, or empty Schema + codegenParameter.isFreeFormObject = true; + + // HTTP request body is free form object + CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema); + if (codegenProperty != null) { + if (StringUtils.isEmpty(bodyParameterName)) { + codegenParameter.baseName = "body"; // default to body + } else { + codegenParameter.baseName = bodyParameterName; + } + codegenParameter.isPrimitiveType = true; + codegenParameter.baseType = codegenProperty.baseType; + codegenParameter.dataType = codegenProperty.dataType; + codegenParameter.description = codegenProperty.description; + codegenParameter.isNullable = codegenProperty.isNullable; + codegenParameter.paramName = toParamName(codegenParameter.baseName); + } + // set nullable + setParameterNullable(codegenParameter, codegenProperty); + } else if (ModelUtils.isObjectSchema(schema)) { + // object type schema or composed schema with properties defined + this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, false); + } + addVarsRequiredVarsAdditionalProps(schema, codegenParameter); + } + + protected void updateRequestBodyForArray(CodegenParameter codegenParameter, Schema schema, String name, Set imports, String bodyParameterName) { + if (ModelUtils.isGenerateAliasAsModel(schema) && StringUtils.isNotBlank(name)) { + this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, true); + } else { + final ArraySchema arraySchema = (ArraySchema) schema; + Schema inner = getSchemaItems(arraySchema); + CodegenProperty codegenProperty = fromProperty("property", arraySchema); + imports.add(codegenProperty.baseType); + CodegenProperty innerCp = codegenProperty; + CodegenProperty mostInnerItem = innerCp; + // loop through multidimensional array to add proper import + // also find the most inner item + while (innerCp != null) { + if (innerCp.complexType != null) { + imports.add(innerCp.complexType); + } + mostInnerItem = innerCp; + innerCp = innerCp.items; + } + + if (StringUtils.isEmpty(bodyParameterName)) { + if (StringUtils.isEmpty(mostInnerItem.complexType)) { + codegenParameter.baseName = "request_body"; + } else { + codegenParameter.baseName = mostInnerItem.complexType; + } + } else { + codegenParameter.baseName = bodyParameterName; + } + codegenParameter.paramName = toArrayModelParamName(codegenParameter.baseName); + codegenParameter.items = codegenProperty.items; + codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; + codegenParameter.dataType = getTypeDeclaration(arraySchema); + codegenParameter.baseType = getSchemaType(inner); + codegenParameter.isContainer = Boolean.TRUE; + codegenParameter.isNullable = codegenProperty.isNullable; + + // set nullable + setParameterNullable(codegenParameter, codegenProperty); + + while (codegenProperty != null) { + imports.add(codegenProperty.baseType); + codegenProperty = codegenProperty.items; + } + } + } + + protected void updateRequestBodyForString(CodegenParameter codegenParameter, Schema schema, Set imports, String bodyParameterName) { + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + if (ModelUtils.isByteArraySchema(schema)) { + codegenParameter.isByteArray = true; + } else if (ModelUtils.isBinarySchema(schema)) { + codegenParameter.isBinary = true; + codegenParameter.isFile = true; // file = binary in OAS3 + } else if (ModelUtils.isUUIDSchema(schema)) { + codegenParameter.isUuid = true; + } else if (ModelUtils.isURISchema(schema)) { + codegenParameter.isUri = true; + } else if (ModelUtils.isEmailSchema(schema)) { + codegenParameter.isEmail = true; + } else if (ModelUtils.isDateSchema(schema)) { // date format + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDate = true; + } else if (ModelUtils.isDateTimeSchema(schema)) { // date-time format + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDateTime = true; + } else if (ModelUtils.isDecimalSchema(schema)) { // type: string, format: number + codegenParameter.isDecimal = true; + codegenParameter.setIsString(false); + } + codegenParameter.pattern = toRegularExpression(schema.getPattern()); + } + public CodegenParameter fromRequestBody(RequestBody body, Set imports, String bodyParameterName) { if (body == null) { LOGGER.error("body in fromRequestBody cannot be null!"); @@ -6271,151 +6579,62 @@ public class DefaultCodegen implements CodegenConfig { if (StringUtils.isNotBlank(schema.get$ref())) { name = ModelUtils.getSimpleRef(schema.get$ref()); } - Schema validationSchema = unaliasSchema(schema, importMapping); + + Schema unaliasedSchema = unaliasSchema(schema, importMapping); schema = ModelUtils.getReferencedSchema(this.openAPI, schema); - ModelUtils.syncValidationProperties(validationSchema, codegenParameter); - - if (ModelUtils.isMapSchema(schema)) { - // Schema with additionalproperties: true (including composed schemas with additionalproperties: true) - if (ModelUtils.isGenerateAliasAsModel(schema) && StringUtils.isNotBlank(name)) { - this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, true); + ModelUtils.syncValidationProperties(unaliasedSchema, codegenParameter); + codegenParameter.setTypeProperties(unaliasedSchema); + // TODO in the future switch al the below schema usages to unaliasedSchema + // because it keeps models as refs and will not get their referenced schemas + if (ModelUtils.isArraySchema(schema)) { + updateRequestBodyForArray(codegenParameter, schema, name, imports, bodyParameterName); + } else if (ModelUtils.isTypeObjectSchema(schema)) { + updateRequestBodyForObject(codegenParameter, schema, name, imports, bodyParameterName); + } else if (ModelUtils.isIntegerSchema(schema)) { // integer type + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + codegenParameter.isNumeric = Boolean.TRUE; + if (ModelUtils.isLongSchema(schema)) { // int64/long format + codegenParameter.isLong = Boolean.TRUE; } else { - Schema inner = getAdditionalProperties(schema); - if (inner == null) { - LOGGER.error("No inner type supplied for map parameter `{}`. Default to type:string", schema.getName()); - inner = new StringSchema().description("//TODO automatically added by openapi-generator"); - schema.setAdditionalProperties(inner); - } - CodegenProperty codegenProperty = fromProperty("property", schema); - - imports.add(codegenProperty.baseType); - - CodegenProperty innerCp = codegenProperty; - while (innerCp != null) { - if (innerCp.complexType != null) { - imports.add(innerCp.complexType); - } - innerCp = innerCp.items; - } - - if (StringUtils.isEmpty(bodyParameterName)) { - codegenParameter.baseName = "request_body"; - } else { - codegenParameter.baseName = bodyParameterName; - } - codegenParameter.paramName = toParamName(codegenParameter.baseName); - codegenParameter.items = codegenProperty.items; - codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; - codegenParameter.dataType = getTypeDeclaration(schema); - codegenParameter.baseType = getSchemaType(inner); - codegenParameter.isContainer = Boolean.TRUE; - codegenParameter.isMap = Boolean.TRUE; - codegenParameter.isNullable = codegenProperty.isNullable; - - setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty); - - // set nullable - setParameterNullable(codegenParameter, codegenProperty); - } - } else if (ModelUtils.isArraySchema(schema)) { - if (ModelUtils.isGenerateAliasAsModel(schema) && StringUtils.isNotBlank(name)) { - this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, true); - } else { - final ArraySchema arraySchema = (ArraySchema) schema; - Schema inner = getSchemaItems(arraySchema); - CodegenProperty codegenProperty = fromProperty("property", arraySchema); - imports.add(codegenProperty.baseType); - CodegenProperty innerCp = codegenProperty; - CodegenProperty mostInnerItem = innerCp; - // loop through multidimensional array to add proper import - // also find the most inner item - while (innerCp != null) { - if (innerCp.complexType != null) { - imports.add(innerCp.complexType); - } - mostInnerItem = innerCp; - innerCp = innerCp.items; - } - - if (StringUtils.isEmpty(bodyParameterName)) { - if (StringUtils.isEmpty(mostInnerItem.complexType)) { - codegenParameter.baseName = "request_body"; - } else { - codegenParameter.baseName = mostInnerItem.complexType; - } - } else { - codegenParameter.baseName = bodyParameterName; - } - codegenParameter.paramName = toArrayModelParamName(codegenParameter.baseName); - codegenParameter.items = codegenProperty.items; - codegenParameter.mostInnerItems = codegenProperty.mostInnerItems; - codegenParameter.dataType = getTypeDeclaration(arraySchema); - codegenParameter.baseType = getSchemaType(inner); - codegenParameter.isContainer = Boolean.TRUE; - codegenParameter.isArray = Boolean.TRUE; - codegenParameter.isNullable = codegenProperty.isNullable; - - setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty); - // set nullable - setParameterNullable(codegenParameter, codegenProperty); - - while (codegenProperty != null) { - imports.add(codegenProperty.baseType); - codegenProperty = codegenProperty.items; + codegenParameter.isInteger = Boolean.TRUE; // older use case, int32 and unbounded int + if (ModelUtils.isShortSchema(schema)) { // int32 + codegenParameter.setIsShort(Boolean.TRUE); } } - } else if (isFreeFormObject(schema)) { - // HTTP request body is free form object - CodegenProperty codegenProperty = fromProperty("FREE_FORM_REQUEST_BODY", schema); - if (codegenProperty != null) { - if (StringUtils.isEmpty(bodyParameterName)) { - codegenParameter.baseName = "body"; // default to body - } else { - codegenParameter.baseName = bodyParameterName; - } - codegenParameter.isPrimitiveType = true; - codegenParameter.baseType = codegenProperty.baseType; - codegenParameter.dataType = codegenProperty.dataType; - codegenParameter.description = codegenProperty.description; - codegenParameter.isNullable = codegenProperty.isNullable; - codegenParameter.paramName = toParamName(codegenParameter.baseName); + } else if (ModelUtils.isBooleanSchema(schema)) { // boolean type + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + } else if (ModelUtils.isFileSchema(schema) && !ModelUtils.isStringSchema(schema)) { + // swagger v2 only, type file + codegenParameter.isFile = true; + } else if (ModelUtils.isStringSchema(schema)) { + updateRequestBodyForString(codegenParameter, schema, imports, bodyParameterName); + } else if (ModelUtils.isNumberSchema(schema)) { + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + codegenParameter.isNumeric = Boolean.TRUE; + if (ModelUtils.isFloatSchema(schema)) { // float + codegenParameter.isFloat = Boolean.TRUE; + } else if (ModelUtils.isDoubleSchema(schema)) { // double + codegenParameter.isDouble = Boolean.TRUE; } - setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty); - // set nullable - setParameterNullable(codegenParameter, codegenProperty); - - } else if (ModelUtils.isObjectSchema(schema) || ModelUtils.isComposedSchema(schema)) { - this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, false); + } else if (ModelUtils.isNullType(schema)) { + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + } else if (ModelUtils.isAnyType(schema)) { + if (ModelUtils.isMapSchema(schema)) { + // Schema with additionalproperties: true (including composed schemas with additionalproperties: true) + updateRequestBodyForMap(codegenParameter, schema, name, imports, bodyParameterName); + } else if (ModelUtils.isComposedSchema(schema)) { + this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, false); + } else if (ModelUtils.isObjectSchema(schema)) { + // object type schema OR (AnyType schema with properties defined) + this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, false); + } + addVarsRequiredVarsAdditionalProps(schema, codegenParameter); } else { - // HTTP request body is primitive type (e.g. integer, string, etc) - CodegenProperty codegenProperty = fromProperty("PRIMITIVE_REQUEST_BODY", schema); - if (codegenProperty != null) { - if (StringUtils.isEmpty(bodyParameterName)) { - codegenParameter.baseName = "body"; // default to body - } else { - codegenParameter.baseName = bodyParameterName; - } - codegenParameter.isNull = codegenProperty.isNull; - codegenParameter.isPrimitiveType = true; - codegenParameter.baseType = codegenProperty.baseType; - codegenParameter.dataType = codegenProperty.dataType; - codegenParameter.description = codegenProperty.description; - codegenParameter.paramName = toParamName(codegenParameter.baseName); - codegenParameter.pattern = codegenProperty.pattern; - codegenParameter.isNullable = codegenProperty.isNullable; - - if (codegenProperty.complexType != null) { - imports.add(codegenProperty.complexType); - } - - } - setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty); - // set nullable - setParameterNullable(codegenParameter, codegenProperty); + // referenced schemas + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); } - addVarsRequiredVarsAdditionalProps(schema, codegenParameter); addJsonSchemaForBodyRequestInCaseItsNotPresent(codegenParameter, body); // set the parameter's example value @@ -6795,6 +7014,9 @@ public class DefaultCodegen implements CodegenConfig { } /** + * This method has been kept to keep the introduction of ModelUtils.isAnyType as a non-breaking change + * this way, existing forks of our generator can continue to use this method + * TODO in 6.0.0 replace this method with ModelUtils.isAnyType * Return true if the schema value can be any type, i.e. it can be * the null value, integer, number, string, object or array. * One use case is when the "type" attribute in the OAS schema is unspecified. @@ -6867,6 +7089,7 @@ public class DefaultCodegen implements CodegenConfig { * @return true if it's a free-form object */ protected boolean isFreeFormObject(Schema schema) { + // TODO remove this method and replace all usages with ModelUtils.isFreeFormObject return ModelUtils.isFreeFormObject(this.openAPI, schema); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java index ffb195c4a5b..b3833e47f6f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java @@ -2,6 +2,9 @@ package org.openapitools.codegen; import java.util.List; +import io.swagger.v3.oas.models.media.Schema; +import org.openapitools.codegen.utils.ModelUtils; + public interface IJsonSchemaValidationProperties { String getPattern(); @@ -71,6 +74,7 @@ public interface IJsonSchemaValidationProperties { void setIsDateTime(boolean isDateTime); + // true when the schema type is object boolean getIsMap(); void setIsMap(boolean isMap); @@ -128,4 +132,77 @@ public interface IJsonSchemaValidationProperties { // discriminators are only supported in request bodies and response payloads per OpenApi void setHasDiscriminatorWithNonEmptyMapping(boolean hasDiscriminatorWithNonEmptyMapping); + + boolean getIsString(); + + void setIsString(boolean isNumber); + + boolean getIsNumber(); + + void setIsNumber(boolean isNumber); + + boolean getIsAnyType(); + + void setIsAnyType(boolean isAnyType); + + /** + * Syncs all the schema's type properties into the IJsonSchemaValidationProperties instance + * for now this only supports types without format information + * TODO: in the future move the format handling in here too + * @param p the schema which contains the type info + */ + default void setTypeProperties(Schema p) { + if (ModelUtils.isTypeObjectSchema(p)) { + setIsMap(true); + } else if (ModelUtils.isArraySchema(p)) { + setIsArray(true); + } else if (ModelUtils.isFileSchema(p) && !ModelUtils.isStringSchema(p)) { + // swagger v2 only, type file + ; + } else if (ModelUtils.isStringSchema(p)) { + setIsString(true); + if (ModelUtils.isByteArraySchema(p)) { + ; + } else if (ModelUtils.isBinarySchema(p)) { + // openapi v3 way of representing binary + file data + // for backward compatibility with 2.x file type + setIsString(false); + } else if (ModelUtils.isUUIDSchema(p)) { + // keep isString to true to make it backward compatible + ; + } else if (ModelUtils.isURISchema(p)) { + ; + } else if (ModelUtils.isEmailSchema(p)) { + ; + } else if (ModelUtils.isDateSchema(p)) { + ; + } else if (ModelUtils.isDateTimeSchema(p)) { + ; + } else if (ModelUtils.isDecimalSchema(p)) { // type: string, format: number + ; + } + } else if (ModelUtils.isNumberSchema(p)) { + if (ModelUtils.isFloatSchema(p)) { // float + ; + } else if (ModelUtils.isDoubleSchema(p)) { // double + ; + } else { // type is number and without format + setIsNumber(true); + } + } else if (ModelUtils.isIntegerSchema(p)) { // integer type + if (ModelUtils.isLongSchema(p)) { // int64/long format + ; + } else if (ModelUtils.isShortSchema(p)) { // int32/short format + ; + } else { // unbounded integer + setIsUnboundedInteger(true); + } + } else if (ModelUtils.isBooleanSchema(p)) { // boolean type + setIsBoolean(true); + } else if (ModelUtils.isNullType(p)) { + setIsNull(true); + } else if (ModelUtils.isAnyType(p)) { + setIsAnyType(true); + } + } } \ No newline at end of file diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java index 20d5bbe6e26..3c3f002b187 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java @@ -401,7 +401,7 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege if (ref != null && !ref.isEmpty()) { type = toModelName(openAPIType); - } else if ("object".equals(openAPIType) && isAnyTypeSchema(p)) { + } else if ("object".equals(openAPIType) && ModelUtils.isAnyType(p)) { // Arbitrary type. Note this is not the same thing as free-form object. type = "interface{}"; } else if (typeMapping.containsKey(openAPIType)) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpNetCoreClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpNetCoreClientCodegen.java index 9a86368bb39..66718bdaf7f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpNetCoreClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpNetCoreClientCodegen.java @@ -19,6 +19,7 @@ package org.openapitools.codegen.languages; import com.google.common.collect.ImmutableMap; import com.samskivert.mustache.Mustache; 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 org.openapitools.codegen.*; import org.openapitools.codegen.meta.features.*; @@ -1128,4 +1129,28 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen { System.out.println("# Please support his work directly via https://patreon.com/jimschubert \uD83D\uDE4F #"); System.out.println("################################################################################"); } + + @Override + protected void updateModelForObject(CodegenModel m, Schema schema) { + /** + * we have a custom version of this function so we only set isMap to true if + * ModelUtils.isMapSchema + * In other generators, isMap is true for all type object schemas + */ + if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) { + // passing null to allProperties and allRequired as there's no parent + addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null); + } + if (ModelUtils.isMapSchema(schema)) { + // an object or anyType composed schema that has additionalProperties set + addAdditionPropertiesToCodeGenModel(m, schema); + } else { + m.setIsMap(false); + if (ModelUtils.isFreeFormObject(openAPI, schema)) { + // non-composed object type with no properties + additionalProperties + // additionalProperties must be null, ObjectSchema, or empty Schema + addAdditionPropertiesToCodeGenModel(m, schema); + } + } + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java index 5f9734460f8..ab4f7b37cf7 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoServerCodegen.java @@ -17,8 +17,11 @@ package org.openapitools.codegen.languages; +import io.swagger.v3.oas.models.media.ComposedSchema; +import io.swagger.v3.oas.models.media.Schema; import org.openapitools.codegen.*; import org.openapitools.codegen.meta.features.*; +import org.openapitools.codegen.utils.ModelUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -359,4 +362,28 @@ public class GoServerCodegen extends AbstractGoCodegen { public void setAddResponseHeaders(Boolean addResponseHeaders) { this.addResponseHeaders = addResponseHeaders; } + + @Override + protected void updateModelForObject(CodegenModel m, Schema schema) { + /** + * we have a custom version of this function so we only set isMap to true if + * ModelUtils.isMapSchema + * In other generators, isMap is true for all type object schemas + */ + if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) { + // passing null to allProperties and allRequired as there's no parent + addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null); + } + if (ModelUtils.isMapSchema(schema)) { + // an object or anyType composed schema that has additionalProperties set + addAdditionPropertiesToCodeGenModel(m, schema); + } else { + m.setIsMap(false); + if (ModelUtils.isFreeFormObject(openAPI, schema)) { + // non-composed object type with no properties + additionalProperties + // additionalProperties must be null, ObjectSchema, or empty Schema + addAdditionPropertiesToCodeGenModel(m, schema); + } + } + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaCXFServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaCXFServerCodegen.java index ae0c006cabd..f406050ea68 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaCXFServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaCXFServerCodegen.java @@ -17,15 +17,20 @@ package org.openapitools.codegen.languages; +import io.swagger.v3.oas.models.media.ComposedSchema; +import io.swagger.v3.oas.models.media.Schema; +import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.CXFServerFeatures; import org.openapitools.codegen.languages.features.GzipTestFeatures; import org.openapitools.codegen.languages.features.LoggingTestFeatures; import org.openapitools.codegen.languages.features.UseGenericResponseFeatures; +import org.openapitools.codegen.utils.ModelUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.util.Set; public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen implements CXFServerFeatures, GzipTestFeatures, LoggingTestFeatures, UseGenericResponseFeatures { @@ -124,7 +129,6 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen } - @Override public void processOpts() { super.processOpts(); @@ -328,4 +332,27 @@ public class JavaCXFServerCodegen extends AbstractJavaJAXRSServerCodegen this.useGenericResponse = useGenericResponse; } + @Override + protected void updateModelForObject(CodegenModel m, Schema schema) { + /** + * we have a custom version of this function so we only set isMap to true if + * ModelUtils.isMapSchema + * In other generators, isMap is true for all type object schemas + */ + if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) { + // passing null to allProperties and allRequired as there's no parent + addVars(m, unaliasPropertySchema(schema.getProperties()), schema.getRequired(), null, null); + } + if (ModelUtils.isMapSchema(schema)) { + // an object or anyType composed schema that has additionalProperties set + addAdditionPropertiesToCodeGenModel(m, schema); + } else { + m.setIsMap(false); + if (ModelUtils.isFreeFormObject(openAPI, schema)) { + // non-composed object type with no properties + additionalProperties + // additionalProperties must be null, ObjectSchema, or empty Schema + addAdditionPropertiesToCodeGenModel(m, schema); + } + } + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index f545e758334..7b66ec98a39 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -849,7 +849,7 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen { return prefix + modelName + fullSuffix; } } - if (isAnyTypeSchema(p)) { + if (ModelUtils.isAnyType(p)) { // for v2 specs only, swagger-parser never generates an AnyType schemas even though it should generate them // https://github.com/swagger-api/swagger-parser/issues/1378 // switch to v3 if you need AnyType to work @@ -1115,7 +1115,7 @@ public class PythonClientCodegen extends PythonLegacyClientCodegen { } String refModelName = getModelName(schema); return toExampleValueRecursive(refModelName, refSchema, objExample, indentationLevel, prefix, exampleLine, seenSchemas); - } else if (ModelUtils.isNullType(schema) || isAnyTypeSchema(schema)) { + } else if (ModelUtils.isNullType(schema) || ModelUtils.isAnyType(schema)) { // The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x, // though this tooling supports it. return fullPrefix + "None" + closeChars; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java index ad6014054cc..9d6546d2ae5 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java @@ -1681,4 +1681,93 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig { } } } + + @Override + protected void updateRequestBodyForString(CodegenParameter codegenParameter, Schema schema, Set imports, String bodyParameterName) { + /** + * we have a custom version of this function to set isString to false for isByteArray + */ + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + if (ModelUtils.isByteArraySchema(schema)) { + codegenParameter.isByteArray = true; + // custom code + codegenParameter.setIsString(false); + } else if (ModelUtils.isBinarySchema(schema)) { + codegenParameter.isBinary = true; + codegenParameter.isFile = true; // file = binary in OAS3 + } else if (ModelUtils.isUUIDSchema(schema)) { + codegenParameter.isUuid = true; + } else if (ModelUtils.isURISchema(schema)) { + codegenParameter.isUri = true; + } else if (ModelUtils.isEmailSchema(schema)) { + codegenParameter.isEmail = true; + } else if (ModelUtils.isDateSchema(schema)) { // date format + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDate = true; + } else if (ModelUtils.isDateTimeSchema(schema)) { // date-time format + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDateTime = true; + } else if (ModelUtils.isDecimalSchema(schema)) { // type: string, format: number + codegenParameter.isDecimal = true; + codegenParameter.setIsString(false); + } + codegenParameter.pattern = toRegularExpression(schema.getPattern()); + } + + @Override + protected void updateParameterForString(CodegenParameter codegenParameter, Schema parameterSchema){ + /** + * we have a custom version of this function to set isString to false for uuid + */ + if (ModelUtils.isEmailSchema(parameterSchema)) { + codegenParameter.isEmail = true; + } else if (ModelUtils.isUUIDSchema(parameterSchema)) { + codegenParameter.setIsString(false); + codegenParameter.isUuid = true; + } else if (ModelUtils.isByteArraySchema(parameterSchema)) { + codegenParameter.setIsString(false); + codegenParameter.isByteArray = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isBinarySchema(parameterSchema)) { + codegenParameter.isBinary = true; + codegenParameter.isFile = true; // file = binary in OAS3 + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateSchema(parameterSchema)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDate = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateTimeSchema(parameterSchema)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDateTime = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDecimalSchema(parameterSchema)) { // type: string, format: number + codegenParameter.setIsString(false); + codegenParameter.isDecimal = true; + codegenParameter.isPrimitiveType = true; + } + if (Boolean.TRUE.equals(codegenParameter.isString)) { + codegenParameter.isPrimitiveType = true; + } + } + + @Override + protected void updatePropertyForAnyType(CodegenProperty property, Schema p) { + /** + * we have a custom version of this function to not set isNullable to true + */ + // The 'null' value is allowed when the OAS schema is 'any type'. + // See https://github.com/OAI/OpenAPI-Specification/issues/1389 + if (Boolean.FALSE.equals(p.getNullable())) { + LOGGER.warn("Schema '{}' is any type, which includes the 'null' value. 'nullable' cannot be set to 'false'", p.getName()); + } + if (languageSpecificPrimitives.contains(property.dataType)) { + property.isPrimitiveType = true; + } + if (ModelUtils.isMapSchema(p)) { + // an object or anyType composed schema that has additionalProperties set + // some of our code assumes that any type schema with properties defined will be a map + // even though it should allow in any type and have map constraints for properties + updatePropertyForMap(property, p); + } + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAxiosClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAxiosClientCodegen.java index b0a38d96c6d..243b6e10db1 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAxiosClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAxiosClientCodegen.java @@ -22,6 +22,8 @@ import io.swagger.v3.parser.util.SchemaTypeUtil; import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.*; import org.openapitools.codegen.meta.features.DocumentationFeature; +import org.openapitools.codegen.utils.ModelUtils; + import java.util.*; public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodegen { @@ -255,4 +257,19 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json")); } + @Override + protected void updatePropertyForAnyType(CodegenProperty property, Schema p) { + // The 'null' value is allowed when the OAS schema is 'any type'. + // See https://github.com/OAI/OpenAPI-Specification/issues/1389 + // custom line here, do not set property.isNullable = true + if (languageSpecificPrimitives.contains(property.dataType)) { + property.isPrimitiveType = true; + } + if (ModelUtils.isMapSchema(p)) { + // an object or anyType composed schema that has additionalProperties set + // some of our code assumes that any type schema with properties defined will be a map + // even though it should allow in any type and have map constraints for properties + updatePropertyForMap(property, p); + } + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java index 3cf310de3d9..b7233be4cb6 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java @@ -1100,7 +1100,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo } String refModelName = getModelName(schema); return toExampleValueRecursive(refModelName, refSchema, objExample, indentationLevel, prefix, exampleLine, seenSchemas); - } else if (ModelUtils.isNullType(schema) || isAnyTypeSchema(schema)) { + } else if (ModelUtils.isNullType(schema) || ModelUtils.isAnyType(schema)) { // The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x, // though this tooling supports it. return fullPrefix + "null" + closeChars; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index a4bc0147c65..e26bbcaa458 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -407,6 +407,21 @@ public class ModelUtils { return ref; } + /** + * Return true if the specified schema is type object + * We can't use isObjectSchema because it requires properties to exist which is not required + * We can't use isMap because it is true for AnyType use cases + * + * @param schema the OAS schema + * @return true if the specified schema is an Object schema. + */ + public static boolean isTypeObjectSchema(Schema schema) { + if (SchemaTypeUtil.OBJECT_TYPE.equals(schema.getType())) { + return true; + } + return false; + } + /** * Return true if the specified schema is an object with a fixed number of properties. * @@ -1487,18 +1502,23 @@ public class ModelUtils { return false; } + /** + * For when a type is not defined on a schema + * Note: properties, additionalProperties, enums, validations, items, and composed schemas (oneOf/anyOf/allOf) + * can be defined or omitted on these any type schemas + * @param schema the schema that we are checking + * @return boolean + */ + public static boolean isAnyType(Schema schema) { + return (schema.get$ref() == null && schema.getType() == null); + } + public static void syncValidationProperties(Schema schema, IJsonSchemaValidationProperties target) { + // TODO move this method to IJsonSchemaValidationProperties if (schema != null && target != null) { if (isNullType(schema) || schema.get$ref() != null || isBooleanSchema(schema)) { return; } - boolean isAnyType = (schema.getClass().equals(Schema.class) && schema.get$ref() == null && schema.getType() == null && - (schema.getProperties() == null || schema.getProperties().isEmpty()) && - schema.getAdditionalProperties() == null && schema.getNot() == null && - schema.getEnum() == null); - if (isAnyType) { - return; - } Integer minItems = schema.getMinItems(); Integer maxItems = schema.getMaxItems(); Boolean uniqueItems = schema.getUniqueItems(); @@ -1515,7 +1535,7 @@ public class ModelUtils { if (isArraySchema(schema)) { setArrayValidations(minItems, maxItems, uniqueItems, target); - } else if (isMapSchema(schema) || isObjectSchema(schema)) { + } else if (isTypeObjectSchema(schema)) { setObjectValidations(minProperties, maxProperties, target); } else if (isStringSchema(schema)) { setStringValidations(minLength, maxLength, pattern, target); @@ -1524,8 +1544,8 @@ public class ModelUtils { } } else if (isNumberSchema(schema) || isIntegerSchema(schema)) { setNumericValidations(schema, multipleOf, minimum, maximum, exclusiveMinimum, exclusiveMaximum, target); - } else if (isComposedSchema(schema)) { - // this could be composed out of anything so set all validations here + } else if (isAnyType(schema)) { + // anyType can have any validations set on it setArrayValidations(minItems, maxItems, uniqueItems, target); setObjectValidations(minProperties, maxProperties, target); setStringValidations(minLength, maxLength, pattern, target); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index 6d74693c21a..83917da4eba 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -3636,4 +3636,214 @@ public class DefaultCodegenTest { co = codegen.fromOperation(path, "GET", operation, null); assertEquals(co.operationId, "getAll"); } + + @Test + public void testComposedPropertyTypes() { + DefaultCodegen codegen = new DefaultCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10330.yaml"); + codegen.setOpenAPI(openAPI); + String modelName; + + modelName = "ObjectWithComposedProperties"; + CodegenModel m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.vars.get(0).getIsMap()); + assertTrue(m.vars.get(1).getIsNumber()); + assertTrue(m.vars.get(2).getIsUnboundedInteger()); + assertTrue(m.vars.get(3).getIsString()); + assertTrue(m.vars.get(4).getIsBoolean()); + assertTrue(m.vars.get(5).getIsArray()); + assertTrue(m.vars.get(6).getIsNull()); + assertTrue(m.vars.get(7).getIsAnyType()); + } + + @Test + public void testComposedModelTypes() { + DefaultCodegen codegen = new DefaultCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10330.yaml"); + codegen.setOpenAPI(openAPI); + String modelName; + CodegenModel m; + + modelName = "ComposedObject"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsMap()); + + modelName = "ComposedNumber"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsNumber()); + + modelName = "ComposedInteger"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsUnboundedInteger()); + + modelName = "ComposedString"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsString()); + + modelName = "ComposedBool"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsBoolean()); + + modelName = "ComposedArray"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsArray()); + + modelName = "ComposedNone"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsNull()); + + modelName = "ComposedAnyType"; + m = codegen.fromModel(modelName, openAPI.getComponents().getSchemas().get(modelName)); + assertTrue(m.getIsAnyType()); + } + + @Test + public void testComposedResponseTypes() { + DefaultCodegen codegen = new DefaultCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10330.yaml"); + codegen.setOpenAPI(openAPI); + String path; + CodegenOperation co; + CodegenResponse cr; + + path = "/ComposedObject"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsMap()); + + path = "/ComposedNumber"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsNumber()); + + path = "/ComposedInteger"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsUnboundedInteger()); + + path = "/ComposedString"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsString()); + + path = "/ComposedBool"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsBoolean()); + + path = "/ComposedArray"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsArray()); + + path = "/ComposedNone"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsNull()); + + path = "/ComposedAnyType"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cr = co.responses.get(0); + assertTrue(cr.getIsAnyType()); + } + + @Test + public void testComposedRequestBodyTypes() { + DefaultCodegen codegen = new DefaultCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10330.yaml"); + codegen.setOpenAPI(openAPI); + String path; + CodegenOperation co; + CodegenParameter cp; + + path = "/ComposedObject"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsMap()); + + path = "/ComposedNumber"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsNumber()); + + path = "/ComposedInteger"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsUnboundedInteger()); + + path = "/ComposedString"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsString()); + + path = "/ComposedBool"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsBoolean()); + + path = "/ComposedArray"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsArray()); + + path = "/ComposedNone"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsNull()); + + path = "/ComposedAnyType"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.bodyParam; + assertTrue(cp.getIsAnyType()); + } + + @Test + public void testComposedRequestQueryParamTypes() { + DefaultCodegen codegen = new DefaultCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_10330.yaml"); + codegen.setOpenAPI(openAPI); + String path; + CodegenOperation co; + CodegenParameter cp; + + path = "/ComposedObject"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsMap()); + + path = "/ComposedNumber"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsNumber()); + + path = "/ComposedInteger"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsUnboundedInteger()); + + path = "/ComposedString"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsString()); + + path = "/ComposedBool"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsBoolean()); + + path = "/ComposedArray"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsArray()); + + path = "/ComposedNone"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsNull()); + + path = "/ComposedAnyType"; + co = codegen.fromOperation(path, "GET", openAPI.getPaths().get(path).getGet(), null); + cp = co.queryParams.get(0); + assertTrue(cp.getIsAnyType()); + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index f034760ea96..c9d4090b050 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -820,6 +820,7 @@ public class JavaClientCodegenTest { Assert.assertTrue(cp3.isAnyType); // map + // Should allow in any type including map, https://github.com/swagger-api/swagger-parser/issues/1603 final CodegenProperty cp4 = cm2.vars.get(3); Assert.assertEquals(cp4.baseName, "map_any_value"); Assert.assertEquals(cp4.dataType, "Map"); @@ -830,6 +831,7 @@ public class JavaClientCodegenTest { Assert.assertTrue(cp4.isFreeFormObject); Assert.assertFalse(cp4.isAnyType); + // Should allow in any type including map, https://github.com/swagger-api/swagger-parser/issues/1603 final CodegenProperty cp5 = cm2.vars.get(4); Assert.assertEquals(cp5.baseName, "map_any_value_with_desc"); Assert.assertEquals(cp5.dataType, "Map"); @@ -840,6 +842,7 @@ public class JavaClientCodegenTest { Assert.assertTrue(cp5.isFreeFormObject); Assert.assertFalse(cp5.isAnyType); + // Should allow in any type including map, https://github.com/swagger-api/swagger-parser/issues/1603 final CodegenProperty cp6 = cm2.vars.get(5); Assert.assertEquals(cp6.baseName, "map_any_value_nullable"); Assert.assertEquals(cp6.dataType, "Map"); @@ -851,6 +854,7 @@ public class JavaClientCodegenTest { Assert.assertFalse(cp6.isAnyType); // array + // Should allow in any type including array, https://github.com/swagger-api/swagger-parser/issues/1603 final CodegenProperty cp7 = cm2.vars.get(6); Assert.assertEquals(cp7.baseName, "array_any_value"); Assert.assertEquals(cp7.dataType, "List"); @@ -861,6 +865,7 @@ public class JavaClientCodegenTest { Assert.assertFalse(cp7.isFreeFormObject); Assert.assertFalse(cp7.isAnyType); + // Should allow in any type including array, https://github.com/swagger-api/swagger-parser/issues/1603 final CodegenProperty cp8 = cm2.vars.get(7); Assert.assertEquals(cp8.baseName, "array_any_value_with_desc"); Assert.assertEquals(cp8.dataType, "List"); @@ -871,6 +876,7 @@ public class JavaClientCodegenTest { Assert.assertFalse(cp8.isFreeFormObject); Assert.assertFalse(cp8.isAnyType); + // Should allow in any type including array, https://github.com/swagger-api/swagger-parser/issues/1603 final CodegenProperty cp9 = cm2.vars.get(8); Assert.assertEquals(cp9.baseName, "array_any_value_nullable"); Assert.assertEquals(cp9.dataType, "List"); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientTest.java index 842d6a2851a..2ba80266215 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientTest.java @@ -360,7 +360,7 @@ public class PythonClientTest { final PythonClientCodegen codegen = new PythonClientCodegen(); OpenAPI openAPI = TestUtils.createOpenAPI(); - final Schema noDefault = new ArraySchema() + final Schema noDefault = new Schema() .type("number") .minimum(new BigDecimal("10")); final Schema hasDefault = new Schema() diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_10330.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_10330.yaml new file mode 100644 index 00000000000..2de767a061f --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_10330.yaml @@ -0,0 +1,289 @@ +openapi: 3.0.1 +info: + title: OpenAPI Petstore + description: "composed schema isX type checks" + license: + name: Apache-2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.0 +servers: + - url: http://petstore.swagger.io:80/v2 +tags: [] +paths: + /ComposedObject: + get: + parameters: + - in: query + name: ComposedObject + schema: + type: object + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + type: object + allOf: + - {} + responses: + '200': + description: ComposedObject + content: + application/json: + schema: + type: object + allOf: + - {} + /ComposedNumber: + get: + parameters: + - in: query + name: ComposedNumber + schema: + type: number + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + type: number + allOf: + - {} + responses: + '200': + description: ComposedNumber + content: + application/json: + schema: + type: number + allOf: + - {} + /ComposedInteger: + get: + parameters: + - in: query + name: ComposedInteger + schema: + type: integer + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + type: integer + allOf: + - {} + responses: + '200': + description: ComposedInteger + content: + application/json: + schema: + type: integer + allOf: + - {} + /ComposedString: + get: + parameters: + - in: query + name: ComposedString + schema: + type: string + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + type: string + allOf: + - {} + responses: + '200': + description: ComposedString + content: + application/json: + schema: + type: string + allOf: + - {} + /ComposedBool: + get: + parameters: + - in: query + name: ComposedBool + schema: + type: boolean + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + type: boolean + allOf: + - {} + responses: + '200': + description: ComposedBool + content: + application/json: + schema: + type: boolean + allOf: + - {} + /ComposedArray: + get: + parameters: + - in: query + name: ComposedArray + schema: + type: array + items: {} + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + type: array + items: {} + allOf: + - {} + responses: + '200': + description: ComposedArray + content: + application/json: + schema: + type: array + items: {} + allOf: + - {} + /ComposedNone: + get: + parameters: + - in: query + name: ComposedNone + schema: + type: 'null' + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + type: 'null' + allOf: + - {} + responses: + '200': + description: ComposedNone + content: + application/json: + schema: + type: 'null' + allOf: + - {} + /ComposedAnyType: + get: + parameters: + - in: query + name: ComposedAnyType + schema: + allOf: + - {} + requestBody: + required: true + content: + application/json: + schema: + allOf: + - {} + responses: + '200': + description: ComposedAnyType + content: + application/json: + schema: + allOf: + - {} +components: + schemas: + ObjectWithComposedProperties: + type: object + properties: + ComposedObject: + type: object + allOf: + - {} + ComposedNumber: + type: number + allOf: + - {} + ComposedInteger: + type: integer + allOf: + - {} + ComposedString: + type: string + allOf: + - {} + ComposedBool: + type: boolean + allOf: + - {} + ComposedArray: + type: array + items: {} + allOf: + - {} + ComposedNone: + type: 'null' + allOf: + - {} + ComposedAnyType: + allOf: + - {} + ComposedObject: + type: object + allOf: + - {} + ComposedNumber: + type: number + allOf: + - {} + ComposedInteger: + type: integer + allOf: + - {} + ComposedString: + type: string + allOf: + - {} + ComposedBool: + type: boolean + allOf: + - {} + ComposedArray: + type: array + items: {} + allOf: + - {} + ComposedNone: + type: 'null' + allOf: + - {} + ComposedAnyType: + allOf: + - {} diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_8052_recursive_model.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_8052_recursive_model.yaml index 6d833b29211..61236123942 100644 --- a/modules/openapi-generator/src/test/resources/3_0/issue_8052_recursive_model.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/issue_8052_recursive_model.yaml @@ -31,14 +31,16 @@ components: GeoJsonGeometry: title: GeoJsonGeometry description: GeoJSON geometry - oneOf: - - $ref: '#/components/schemas/Point' - - $ref: '#/components/schemas/GeometryCollection' - discriminator: - propertyName: type - mapping: - Point: '#/components/schemas/Point' - GeometryCollection: '#/components/schemas/GeometryCollection' + type: object + properties: + type: + type: string + enum: + - GeometryCollection + geometries: + type: array + items: + $ref: '#/components/schemas/GeoJsonGeometry' externalDocs: url: http://geojson.org/geojson-spec.html#geometry-objects Point: diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/FakeApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/FakeApi.md index da4826633d3..87c4c957148 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/FakeApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/FakeApi.md @@ -766,9 +766,9 @@ namespace Example Configuration config = new Configuration(); config.BasePath = "http://petstore.swagger.io:80/v2"; var apiInstance = new FakeApi(config); - var enumHeaderStringArray = enumHeaderStringArray_example; // List | Header parameter enum test (string array) (optional) + var enumHeaderStringArray = new List(); // List | Header parameter enum test (string array) (optional) var enumHeaderString = enumHeaderString_example; // string | Header parameter enum test (string) (optional) (default to -efg) - var enumQueryStringArray = enumQueryStringArray_example; // List | Query parameter enum test (string array) (optional) + var enumQueryStringArray = new List(); // List | Query parameter enum test (string array) (optional) var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg) var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional) var enumQueryDouble = 1.2D; // double? | Query parameter enum test (double) (optional) @@ -795,9 +795,9 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enumHeaderStringArray** | **List<string>**| Header parameter enum test (string array) | [optional] + **enumHeaderStringArray** | [**List<string>**](string.md)| Header parameter enum test (string array) | [optional] **enumHeaderString** | **string**| Header parameter enum test (string) | [optional] [default to -efg] - **enumQueryStringArray** | **List<string>**| Query parameter enum test (string array) | [optional] + **enumQueryStringArray** | [**List<string>**](string.md)| Query parameter enum test (string array) | [optional] **enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg] **enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional] **enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional] diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/PetApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/PetApi.md index 47820f406dd..aa5cd9f497b 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/PetApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-ConditionalSerialization/docs/PetApi.md @@ -187,7 +187,7 @@ namespace Example config.AccessToken = "YOUR_ACCESS_TOKEN"; var apiInstance = new PetApi(config); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -210,7 +210,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/FakeApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/FakeApi.md index e1431af8135..635f38544d5 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/FakeApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/FakeApi.md @@ -810,9 +810,9 @@ namespace Example HttpClient httpClient = new HttpClient(); HttpClientHandler httpClientHandler = new HttpClientHandler(); var apiInstance = new FakeApi(httpClient, config, httpClientHandler); - var enumHeaderStringArray = enumHeaderStringArray_example; // List | Header parameter enum test (string array) (optional) + var enumHeaderStringArray = new List(); // List | Header parameter enum test (string array) (optional) var enumHeaderString = enumHeaderString_example; // string | Header parameter enum test (string) (optional) (default to -efg) - var enumQueryStringArray = enumQueryStringArray_example; // List | Query parameter enum test (string array) (optional) + var enumQueryStringArray = new List(); // List | Query parameter enum test (string array) (optional) var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg) var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional) var enumQueryDouble = 1.2D; // double? | Query parameter enum test (double) (optional) @@ -839,9 +839,9 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enumHeaderStringArray** | **List<string>**| Header parameter enum test (string array) | [optional] + **enumHeaderStringArray** | [**List<string>**](string.md)| Header parameter enum test (string array) | [optional] **enumHeaderString** | **string**| Header parameter enum test (string) | [optional] [default to -efg] - **enumQueryStringArray** | **List<string>**| Query parameter enum test (string array) | [optional] + **enumQueryStringArray** | [**List<string>**](string.md)| Query parameter enum test (string array) | [optional] **enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg] **enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional] **enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional] diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/PetApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/PetApi.md index 02d0e8e111a..43033c45b59 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/PetApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/docs/PetApi.md @@ -199,7 +199,7 @@ namespace Example HttpClient httpClient = new HttpClient(); HttpClientHandler httpClientHandler = new HttpClientHandler(); var apiInstance = new PetApi(httpClient, config, httpClientHandler); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -222,7 +222,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/FakeApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/FakeApi.md index da4826633d3..87c4c957148 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/FakeApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/FakeApi.md @@ -766,9 +766,9 @@ namespace Example Configuration config = new Configuration(); config.BasePath = "http://petstore.swagger.io:80/v2"; var apiInstance = new FakeApi(config); - var enumHeaderStringArray = enumHeaderStringArray_example; // List | Header parameter enum test (string array) (optional) + var enumHeaderStringArray = new List(); // List | Header parameter enum test (string array) (optional) var enumHeaderString = enumHeaderString_example; // string | Header parameter enum test (string) (optional) (default to -efg) - var enumQueryStringArray = enumQueryStringArray_example; // List | Query parameter enum test (string array) (optional) + var enumQueryStringArray = new List(); // List | Query parameter enum test (string array) (optional) var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg) var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional) var enumQueryDouble = 1.2D; // double? | Query parameter enum test (double) (optional) @@ -795,9 +795,9 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enumHeaderStringArray** | **List<string>**| Header parameter enum test (string array) | [optional] + **enumHeaderStringArray** | [**List<string>**](string.md)| Header parameter enum test (string array) | [optional] **enumHeaderString** | **string**| Header parameter enum test (string) | [optional] [default to -efg] - **enumQueryStringArray** | **List<string>**| Query parameter enum test (string array) | [optional] + **enumQueryStringArray** | [**List<string>**](string.md)| Query parameter enum test (string array) | [optional] **enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg] **enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional] **enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional] diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/PetApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/PetApi.md index 47820f406dd..aa5cd9f497b 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/PetApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-net47/docs/PetApi.md @@ -187,7 +187,7 @@ namespace Example config.AccessToken = "YOUR_ACCESS_TOKEN"; var apiInstance = new PetApi(config); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -210,7 +210,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/FakeApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/FakeApi.md index da4826633d3..87c4c957148 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/FakeApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/FakeApi.md @@ -766,9 +766,9 @@ namespace Example Configuration config = new Configuration(); config.BasePath = "http://petstore.swagger.io:80/v2"; var apiInstance = new FakeApi(config); - var enumHeaderStringArray = enumHeaderStringArray_example; // List | Header parameter enum test (string array) (optional) + var enumHeaderStringArray = new List(); // List | Header parameter enum test (string array) (optional) var enumHeaderString = enumHeaderString_example; // string | Header parameter enum test (string) (optional) (default to -efg) - var enumQueryStringArray = enumQueryStringArray_example; // List | Query parameter enum test (string array) (optional) + var enumQueryStringArray = new List(); // List | Query parameter enum test (string array) (optional) var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg) var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional) var enumQueryDouble = 1.2D; // double? | Query parameter enum test (double) (optional) @@ -795,9 +795,9 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enumHeaderStringArray** | **List<string>**| Header parameter enum test (string array) | [optional] + **enumHeaderStringArray** | [**List<string>**](string.md)| Header parameter enum test (string array) | [optional] **enumHeaderString** | **string**| Header parameter enum test (string) | [optional] [default to -efg] - **enumQueryStringArray** | **List<string>**| Query parameter enum test (string array) | [optional] + **enumQueryStringArray** | [**List<string>**](string.md)| Query parameter enum test (string array) | [optional] **enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg] **enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional] **enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional] diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/PetApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/PetApi.md index 47820f406dd..aa5cd9f497b 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/PetApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-net5.0/docs/PetApi.md @@ -187,7 +187,7 @@ namespace Example config.AccessToken = "YOUR_ACCESS_TOKEN"; var apiInstance = new PetApi(config); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -210,7 +210,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/FakeApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/FakeApi.md index da4826633d3..87c4c957148 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/FakeApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/FakeApi.md @@ -766,9 +766,9 @@ namespace Example Configuration config = new Configuration(); config.BasePath = "http://petstore.swagger.io:80/v2"; var apiInstance = new FakeApi(config); - var enumHeaderStringArray = enumHeaderStringArray_example; // List | Header parameter enum test (string array) (optional) + var enumHeaderStringArray = new List(); // List | Header parameter enum test (string array) (optional) var enumHeaderString = enumHeaderString_example; // string | Header parameter enum test (string) (optional) (default to -efg) - var enumQueryStringArray = enumQueryStringArray_example; // List | Query parameter enum test (string array) (optional) + var enumQueryStringArray = new List(); // List | Query parameter enum test (string array) (optional) var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg) var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional) var enumQueryDouble = 1.2D; // double? | Query parameter enum test (double) (optional) @@ -795,9 +795,9 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enumHeaderStringArray** | **List<string>**| Header parameter enum test (string array) | [optional] + **enumHeaderStringArray** | [**List<string>**](string.md)| Header parameter enum test (string array) | [optional] **enumHeaderString** | **string**| Header parameter enum test (string) | [optional] [default to -efg] - **enumQueryStringArray** | **List<string>**| Query parameter enum test (string array) | [optional] + **enumQueryStringArray** | [**List<string>**](string.md)| Query parameter enum test (string array) | [optional] **enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg] **enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional] **enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional] diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/PetApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/PetApi.md index 47820f406dd..aa5cd9f497b 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/PetApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient/docs/PetApi.md @@ -187,7 +187,7 @@ namespace Example config.AccessToken = "YOUR_ACCESS_TOKEN"; var apiInstance = new PetApi(config); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -210,7 +210,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/FakeApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/FakeApi.md index da4826633d3..87c4c957148 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/FakeApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/FakeApi.md @@ -766,9 +766,9 @@ namespace Example Configuration config = new Configuration(); config.BasePath = "http://petstore.swagger.io:80/v2"; var apiInstance = new FakeApi(config); - var enumHeaderStringArray = enumHeaderStringArray_example; // List | Header parameter enum test (string array) (optional) + var enumHeaderStringArray = new List(); // List | Header parameter enum test (string array) (optional) var enumHeaderString = enumHeaderString_example; // string | Header parameter enum test (string) (optional) (default to -efg) - var enumQueryStringArray = enumQueryStringArray_example; // List | Query parameter enum test (string array) (optional) + var enumQueryStringArray = new List(); // List | Query parameter enum test (string array) (optional) var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg) var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional) var enumQueryDouble = 1.2D; // double? | Query parameter enum test (double) (optional) @@ -795,9 +795,9 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enumHeaderStringArray** | **List<string>**| Header parameter enum test (string array) | [optional] + **enumHeaderStringArray** | [**List<string>**](string.md)| Header parameter enum test (string array) | [optional] **enumHeaderString** | **string**| Header parameter enum test (string) | [optional] [default to -efg] - **enumQueryStringArray** | **List<string>**| Query parameter enum test (string array) | [optional] + **enumQueryStringArray** | [**List<string>**](string.md)| Query parameter enum test (string array) | [optional] **enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg] **enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional] **enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional] diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/PetApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/PetApi.md index 47820f406dd..aa5cd9f497b 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/PetApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClientCore/docs/PetApi.md @@ -187,7 +187,7 @@ namespace Example config.AccessToken = "YOUR_ACCESS_TOKEN"; var apiInstance = new PetApi(config); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -210,7 +210,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClientCoreAndNet47/docs/PetApi.md b/samples/client/petstore/csharp-netcore/OpenAPIClientCoreAndNet47/docs/PetApi.md index 5c589fb2d9a..4baa360aa75 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClientCoreAndNet47/docs/PetApi.md +++ b/samples/client/petstore/csharp-netcore/OpenAPIClientCoreAndNet47/docs/PetApi.md @@ -188,7 +188,7 @@ namespace Example config.AccessToken = "YOUR_ACCESS_TOKEN"; var apiInstance = new PetApi(config); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -211,7 +211,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/csharp/OpenAPIClient/docs/FakeApi.md b/samples/client/petstore/csharp/OpenAPIClient/docs/FakeApi.md index f138a6abd27..b38dea5dd37 100644 --- a/samples/client/petstore/csharp/OpenAPIClient/docs/FakeApi.md +++ b/samples/client/petstore/csharp/OpenAPIClient/docs/FakeApi.md @@ -976,9 +976,9 @@ namespace Example { Configuration.Default.BasePath = "http://petstore.swagger.io:80/v2"; var apiInstance = new FakeApi(Configuration.Default); - var enumHeaderStringArray = enumHeaderStringArray_example; // List | Header parameter enum test (string array) (optional) + var enumHeaderStringArray = new List(); // List | Header parameter enum test (string array) (optional) var enumHeaderString = enumHeaderString_example; // string | Header parameter enum test (string) (optional) (default to -efg) - var enumQueryStringArray = enumQueryStringArray_example; // List | Query parameter enum test (string array) (optional) + var enumQueryStringArray = new List(); // List | Query parameter enum test (string array) (optional) var enumQueryString = enumQueryString_example; // string | Query parameter enum test (string) (optional) (default to -efg) var enumQueryInteger = 56; // int? | Query parameter enum test (double) (optional) var enumQueryDouble = 1.2D; // double? | Query parameter enum test (double) (optional) @@ -1006,9 +1006,9 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **enumHeaderStringArray** | **List<string>**| Header parameter enum test (string array) | [optional] + **enumHeaderStringArray** | [**List<string>**](string.md)| Header parameter enum test (string array) | [optional] **enumHeaderString** | **string**| Header parameter enum test (string) | [optional] [default to -efg] - **enumQueryStringArray** | **List<string>**| Query parameter enum test (string array) | [optional] + **enumQueryStringArray** | [**List<string>**](string.md)| Query parameter enum test (string array) | [optional] **enumQueryString** | **string**| Query parameter enum test (string) | [optional] [default to -efg] **enumQueryInteger** | **int?**| Query parameter enum test (double) | [optional] **enumQueryDouble** | **double?**| Query parameter enum test (double) | [optional] diff --git a/samples/client/petstore/csharp/OpenAPIClient/docs/PetApi.md b/samples/client/petstore/csharp/OpenAPIClient/docs/PetApi.md index 7f8dd7f0fb8..8675820ce21 100644 --- a/samples/client/petstore/csharp/OpenAPIClient/docs/PetApi.md +++ b/samples/client/petstore/csharp/OpenAPIClient/docs/PetApi.md @@ -200,7 +200,7 @@ namespace Example Configuration.Default.AccessToken = "YOUR_ACCESS_TOKEN"; var apiInstance = new PetApi(Configuration.Default); - var status = status_example; // List | Status values that need to be considered for filter + var status = new List(); // List | Status values that need to be considered for filter try { @@ -224,7 +224,7 @@ namespace Example Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **status** | **List<string>**| Status values that need to be considered for filter | + **status** | [**List<string>**](string.md)| Status values that need to be considered for filter | ### Return type diff --git a/samples/client/petstore/java/apache-httpclient/docs/FakeApi.md b/samples/client/petstore/java/apache-httpclient/docs/FakeApi.md index c76fd80c324..6ced5f29b12 100644 --- a/samples/client/petstore/java/apache-httpclient/docs/FakeApi.md +++ b/samples/client/petstore/java/apache-httpclient/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/google-api-client/docs/FakeApi.md b/samples/client/petstore/java/google-api-client/docs/FakeApi.md index c76fd80c324..6ced5f29b12 100644 --- a/samples/client/petstore/java/google-api-client/docs/FakeApi.md +++ b/samples/client/petstore/java/google-api-client/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/jersey1/docs/FakeApi.md b/samples/client/petstore/java/jersey1/docs/FakeApi.md index c76fd80c324..6ced5f29b12 100644 --- a/samples/client/petstore/java/jersey1/docs/FakeApi.md +++ b/samples/client/petstore/java/jersey1/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/jersey2-java8-localdatetime/docs/FakeApi.md b/samples/client/petstore/java/jersey2-java8-localdatetime/docs/FakeApi.md index c538fd7fcd4..5537ee8e911 100644 --- a/samples/client/petstore/java/jersey2-java8-localdatetime/docs/FakeApi.md +++ b/samples/client/petstore/java/jersey2-java8-localdatetime/docs/FakeApi.md @@ -673,7 +673,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/jersey2-java8/docs/FakeApi.md b/samples/client/petstore/java/jersey2-java8/docs/FakeApi.md index 29f79920394..dea5e70e5cc 100644 --- a/samples/client/petstore/java/jersey2-java8/docs/FakeApi.md +++ b/samples/client/petstore/java/jersey2-java8/docs/FakeApi.md @@ -673,7 +673,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/native-async/docs/FakeApi.md b/samples/client/petstore/java/native-async/docs/FakeApi.md index fd327749d6c..c71305325f7 100644 --- a/samples/client/petstore/java/native-async/docs/FakeApi.md +++ b/samples/client/petstore/java/native-async/docs/FakeApi.md @@ -1411,7 +1411,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { CompletableFuture result = apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); @@ -1492,7 +1492,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { CompletableFuture> response = apiInstance.testEnumParametersWithHttpInfo(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/native/docs/FakeApi.md b/samples/client/petstore/java/native/docs/FakeApi.md index 1d0e8ca9ebb..54ffb0467a3 100644 --- a/samples/client/petstore/java/native/docs/FakeApi.md +++ b/samples/client/petstore/java/native/docs/FakeApi.md @@ -1329,7 +1329,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); @@ -1409,7 +1409,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { ApiResponse response = apiInstance.testEnumParametersWithHttpInfo(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/okhttp-gson-dynamicOperations/docs/FakeApi.md b/samples/client/petstore/java/okhttp-gson-dynamicOperations/docs/FakeApi.md index 5a20b8b1911..ed2724757ee 100644 --- a/samples/client/petstore/java/okhttp-gson-dynamicOperations/docs/FakeApi.md +++ b/samples/client/petstore/java/okhttp-gson-dynamicOperations/docs/FakeApi.md @@ -636,7 +636,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/okhttp-gson-parcelableModel/docs/FakeApi.md b/samples/client/petstore/java/okhttp-gson-parcelableModel/docs/FakeApi.md index 5a20b8b1911..ed2724757ee 100644 --- a/samples/client/petstore/java/okhttp-gson-parcelableModel/docs/FakeApi.md +++ b/samples/client/petstore/java/okhttp-gson-parcelableModel/docs/FakeApi.md @@ -636,7 +636,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/okhttp-gson/docs/FakeApi.md b/samples/client/petstore/java/okhttp-gson/docs/FakeApi.md index 5a20b8b1911..ed2724757ee 100644 --- a/samples/client/petstore/java/okhttp-gson/docs/FakeApi.md +++ b/samples/client/petstore/java/okhttp-gson/docs/FakeApi.md @@ -636,7 +636,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/resteasy/docs/FakeApi.md b/samples/client/petstore/java/resteasy/docs/FakeApi.md index c76fd80c324..6ced5f29b12 100644 --- a/samples/client/petstore/java/resteasy/docs/FakeApi.md +++ b/samples/client/petstore/java/resteasy/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/resttemplate-withXml/docs/FakeApi.md b/samples/client/petstore/java/resttemplate-withXml/docs/FakeApi.md index c76fd80c324..6ced5f29b12 100644 --- a/samples/client/petstore/java/resttemplate-withXml/docs/FakeApi.md +++ b/samples/client/petstore/java/resttemplate-withXml/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/resttemplate/docs/FakeApi.md b/samples/client/petstore/java/resttemplate/docs/FakeApi.md index c76fd80c324..6ced5f29b12 100644 --- a/samples/client/petstore/java/resttemplate/docs/FakeApi.md +++ b/samples/client/petstore/java/resttemplate/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/retrofit2-play26/docs/FakeApi.md b/samples/client/petstore/java/retrofit2-play26/docs/FakeApi.md index d0080643e4b..45cf7beb069 100644 --- a/samples/client/petstore/java/retrofit2-play26/docs/FakeApi.md +++ b/samples/client/petstore/java/retrofit2-play26/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/retrofit2/docs/FakeApi.md b/samples/client/petstore/java/retrofit2/docs/FakeApi.md index d0080643e4b..45cf7beb069 100644 --- a/samples/client/petstore/java/retrofit2/docs/FakeApi.md +++ b/samples/client/petstore/java/retrofit2/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/retrofit2rx2/docs/FakeApi.md b/samples/client/petstore/java/retrofit2rx2/docs/FakeApi.md index d0080643e4b..45cf7beb069 100644 --- a/samples/client/petstore/java/retrofit2rx2/docs/FakeApi.md +++ b/samples/client/petstore/java/retrofit2rx2/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/retrofit2rx3/docs/FakeApi.md b/samples/client/petstore/java/retrofit2rx3/docs/FakeApi.md index d0080643e4b..45cf7beb069 100644 --- a/samples/client/petstore/java/retrofit2rx3/docs/FakeApi.md +++ b/samples/client/petstore/java/retrofit2rx3/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/vertx-no-nullable/docs/FakeApi.md b/samples/client/petstore/java/vertx-no-nullable/docs/FakeApi.md index 99c87b67656..a676a4353fd 100644 --- a/samples/client/petstore/java/vertx-no-nullable/docs/FakeApi.md +++ b/samples/client/petstore/java/vertx-no-nullable/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/vertx/docs/FakeApi.md b/samples/client/petstore/java/vertx/docs/FakeApi.md index 99c87b67656..a676a4353fd 100644 --- a/samples/client/petstore/java/vertx/docs/FakeApi.md +++ b/samples/client/petstore/java/vertx/docs/FakeApi.md @@ -674,7 +674,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/java/webclient/docs/FakeApi.md b/samples/client/petstore/java/webclient/docs/FakeApi.md index c3ed83515d1..3a9198107b9 100644 --- a/samples/client/petstore/java/webclient/docs/FakeApi.md +++ b/samples/client/petstore/java/webclient/docs/FakeApi.md @@ -872,7 +872,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/client/petstore/javascript-es6/docs/FakeApi.md b/samples/client/petstore/javascript-es6/docs/FakeApi.md index aa1af642c66..9e35bf405c8 100644 --- a/samples/client/petstore/javascript-es6/docs/FakeApi.md +++ b/samples/client/petstore/javascript-es6/docs/FakeApi.md @@ -625,7 +625,7 @@ let opts = { 'enumQueryString': "'-efg'", // String | Query parameter enum test (string) 'enumQueryInteger': 56, // Number | Query parameter enum test (double) 'enumQueryDouble': 3.4, // Number | Query parameter enum test (double) - 'enumFormStringArray': "'$'", // [String] | Form parameter enum test (string array) + 'enumFormStringArray': ["'$'"], // [String] | Form parameter enum test (string array) 'enumFormString': "'-efg'" // String | Form parameter enum test (string) }; apiInstance.testEnumParameters(opts, (error, data, response) => { diff --git a/samples/client/petstore/javascript-promise-es6/docs/FakeApi.md b/samples/client/petstore/javascript-promise-es6/docs/FakeApi.md index ed68b81f16e..9f1d7e3e721 100644 --- a/samples/client/petstore/javascript-promise-es6/docs/FakeApi.md +++ b/samples/client/petstore/javascript-promise-es6/docs/FakeApi.md @@ -613,7 +613,7 @@ let opts = { 'enumQueryString': "'-efg'", // String | Query parameter enum test (string) 'enumQueryInteger': 56, // Number | Query parameter enum test (double) 'enumQueryDouble': 3.4, // Number | Query parameter enum test (double) - 'enumFormStringArray': "'$'", // [String] | Form parameter enum test (string array) + 'enumFormStringArray': ["'$'"], // [String] | Form parameter enum test (string array) 'enumFormString': "'-efg'" // String | Form parameter enum test (string) }; apiInstance.testEnumParameters(opts).then(() => { diff --git a/samples/client/petstore/php/OpenAPIClient-php/docs/Api/FakeApi.md b/samples/client/petstore/php/OpenAPIClient-php/docs/Api/FakeApi.md index 840d51e0678..3f3d9d9bc39 100644 --- a/samples/client/petstore/php/OpenAPIClient-php/docs/Api/FakeApi.md +++ b/samples/client/petstore/php/OpenAPIClient-php/docs/Api/FakeApi.md @@ -750,7 +750,7 @@ $enum_query_string_array = array('enum_query_string_array_example'); // string[] $enum_query_string = '-efg'; // string | Query parameter enum test (string) $enum_query_integer = 56; // int | Query parameter enum test (double) $enum_query_double = 3.4; // double | Query parameter enum test (double) -$enum_form_string_array = '$'; // string[] | Form parameter enum test (string array) +$enum_form_string_array = array('$'); // string[] | Form parameter enum test (string array) $enum_form_string = '-efg'; // string | Form parameter enum test (string) try { diff --git a/samples/client/petstore/python/docs/FakeApi.md b/samples/client/petstore/python/docs/FakeApi.md index 62754a474ed..c52fe144aba 100644 --- a/samples/client/petstore/python/docs/FakeApi.md +++ b/samples/client/petstore/python/docs/FakeApi.md @@ -973,7 +973,9 @@ with petstore_api.ApiClient() as api_client: enum_query_string = "-efg" # str | Query parameter enum test (string) (optional) if omitted the server will use the default value of "-efg" enum_query_integer = 1 # int | Query parameter enum test (double) (optional) enum_query_double = 1.1 # float | Query parameter enum test (double) (optional) - enum_form_string_array = "$" # [str] | Form parameter enum test (string array) (optional) if omitted the server will use the default value of "$" + enum_form_string_array = [ + "$", + ] # [str] | Form parameter enum test (string array) (optional) if omitted the server will use the default value of "$" enum_form_string = "-efg" # str | Form parameter enum test (string) (optional) if omitted the server will use the default value of "-efg" # example passing only required values which don't have defaults set diff --git a/samples/client/petstore/python/docs/PetApi.md b/samples/client/petstore/python/docs/PetApi.md index a3fc6a60673..70252451912 100644 --- a/samples/client/petstore/python/docs/PetApi.md +++ b/samples/client/petstore/python/docs/PetApi.md @@ -657,7 +657,9 @@ with petstore_api.ApiClient(configuration) as api_client: pet_id = 1 # int | ID of pet to update additional_metadata = "additional_metadata_example" # str | Additional data to pass to server (optional) file = open('/path/to/file', 'rb') # file_type | file to upload (optional) - files = # [file_type] | files to upload (optional) + files = [ +null, + ] # [file_type] | files to upload (optional) # example passing only required values which don't have defaults set try: diff --git a/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/FakeApi.md b/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/FakeApi.md index 62754a474ed..c52fe144aba 100644 --- a/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/FakeApi.md +++ b/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/FakeApi.md @@ -973,7 +973,9 @@ with petstore_api.ApiClient() as api_client: enum_query_string = "-efg" # str | Query parameter enum test (string) (optional) if omitted the server will use the default value of "-efg" enum_query_integer = 1 # int | Query parameter enum test (double) (optional) enum_query_double = 1.1 # float | Query parameter enum test (double) (optional) - enum_form_string_array = "$" # [str] | Form parameter enum test (string array) (optional) if omitted the server will use the default value of "$" + enum_form_string_array = [ + "$", + ] # [str] | Form parameter enum test (string array) (optional) if omitted the server will use the default value of "$" enum_form_string = "-efg" # str | Form parameter enum test (string) (optional) if omitted the server will use the default value of "-efg" # example passing only required values which don't have defaults set diff --git a/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/PetApi.md b/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/PetApi.md index a3fc6a60673..70252451912 100644 --- a/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/PetApi.md +++ b/samples/client/petstore/python_disallowAdditionalPropertiesIfNotPresent/docs/PetApi.md @@ -657,7 +657,9 @@ with petstore_api.ApiClient(configuration) as api_client: pet_id = 1 # int | ID of pet to update additional_metadata = "additional_metadata_example" # str | Additional data to pass to server (optional) file = open('/path/to/file', 'rb') # file_type | file to upload (optional) - files = # [file_type] | files to upload (optional) + files = [ +null, + ] # [file_type] | files to upload (optional) # example passing only required values which don't have defaults set try: diff --git a/samples/client/petstore/typescript-axios/builds/with-fake-endpoints-models-for-testing-with-http-signature/api.ts b/samples/client/petstore/typescript-axios/builds/with-fake-endpoints-models-for-testing-with-http-signature/api.ts index e4cb9ef5c32..431d6261ab3 100644 --- a/samples/client/petstore/typescript-axios/builds/with-fake-endpoints-models-for-testing-with-http-signature/api.ts +++ b/samples/client/petstore/typescript-axios/builds/with-fake-endpoints-models-for-testing-with-http-signature/api.ts @@ -1300,7 +1300,7 @@ export interface User { * @type {any} * @memberof User */ - arbitraryTypeValue?: any | null; + arbitraryTypeValue?: any; /** * test code generation for any type Value can be any type - string, number, boolean, array, object or the \'null\' value. * @type {any} diff --git a/samples/openapi3/client/elm/src/Api/Request/Default.elm b/samples/openapi3/client/elm/src/Api/Request/Default.elm index 23e998284eb..43812738072 100644 --- a/samples/openapi3/client/elm/src/Api/Request/Default.elm +++ b/samples/openapi3/client/elm/src/Api/Request/Default.elm @@ -186,7 +186,7 @@ uuidGet value_query = "GET" "/uuid" [] - [ ( "value", Maybe.map Uuid.toString value_query ) ] + [ ( "value", Maybe.map identityUuid.toString value_query ) ] [] Nothing Uuid.decoder diff --git a/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/doc/FakeApi.md b/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/doc/FakeApi.md index 544b6e316c3..740e5ee6683 100644 --- a/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/doc/FakeApi.md +++ b/samples/openapi3/client/petstore/dart-dio-next/petstore_client_lib_fake/doc/FakeApi.md @@ -585,7 +585,7 @@ final BuiltList enumQueryStringArray = ; // BuiltList | Query pa final String enumQueryString = enumQueryString_example; // String | Query parameter enum test (string) final int enumQueryInteger = 56; // int | Query parameter enum test (double) final double enumQueryDouble = 1.2; // double | Query parameter enum test (double) -final BuiltList enumFormStringArray = enumFormStringArray_example; // BuiltList | Form parameter enum test (string array) +final BuiltList enumFormStringArray = ; // BuiltList | Form parameter enum test (string array) final String enumFormString = enumFormString_example; // String | Form parameter enum test (string) try { diff --git a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/doc/FakeApi.md b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/doc/FakeApi.md index ddd5068fa40..46b337cdc18 100644 --- a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/doc/FakeApi.md +++ b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/doc/FakeApi.md @@ -585,7 +585,7 @@ var enumQueryStringArray = []; // BuiltList | Query parameter enum test var enumQueryString = enumQueryString_example; // String | Query parameter enum test (string) var enumQueryInteger = 56; // int | Query parameter enum test (double) var enumQueryDouble = 1.2; // double | Query parameter enum test (double) -var enumFormStringArray = [enumFormStringArray_example]; // BuiltList | Form parameter enum test (string array) +var enumFormStringArray = []; // BuiltList | Form parameter enum test (string array) var enumFormString = enumFormString_example; // String | Form parameter enum test (string) try { diff --git a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/FakeApi.md b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/FakeApi.md index 3f4460fa623..869c513b1f2 100644 --- a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/FakeApi.md +++ b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/FakeApi.md @@ -582,7 +582,7 @@ final enumQueryStringArray = []; // List | Query parameter enum test (st final enumQueryString = enumQueryString_example; // String | Query parameter enum test (string) final enumQueryInteger = 56; // int | Query parameter enum test (double) final enumQueryDouble = 1.2; // double | Query parameter enum test (double) -final enumFormStringArray = [enumFormStringArray_example]; // List | Form parameter enum test (string array) +final enumFormStringArray = []; // List | Form parameter enum test (string array) final enumFormString = enumFormString_example; // String | Form parameter enum test (string) try { diff --git a/samples/openapi3/client/petstore/dart2/petstore_json_serializable_client_lib_fake/doc/FakeApi.md b/samples/openapi3/client/petstore/dart2/petstore_json_serializable_client_lib_fake/doc/FakeApi.md index 3f4460fa623..869c513b1f2 100644 --- a/samples/openapi3/client/petstore/dart2/petstore_json_serializable_client_lib_fake/doc/FakeApi.md +++ b/samples/openapi3/client/petstore/dart2/petstore_json_serializable_client_lib_fake/doc/FakeApi.md @@ -582,7 +582,7 @@ final enumQueryStringArray = []; // List | Query parameter enum test (st final enumQueryString = enumQueryString_example; // String | Query parameter enum test (string) final enumQueryInteger = 56; // int | Query parameter enum test (double) final enumQueryDouble = 1.2; // double | Query parameter enum test (double) -final enumFormStringArray = [enumFormStringArray_example]; // List | Form parameter enum test (string array) +final enumFormStringArray = []; // List | Form parameter enum test (string array) final enumFormString = enumFormString_example; // String | Form parameter enum test (string) try { diff --git a/samples/openapi3/client/petstore/java/jersey2-java8/docs/FakeApi.md b/samples/openapi3/client/petstore/java/jersey2-java8/docs/FakeApi.md index 32a66fa54dc..def65c4c88e 100644 --- a/samples/openapi3/client/petstore/java/jersey2-java8/docs/FakeApi.md +++ b/samples/openapi3/client/petstore/java/jersey2-java8/docs/FakeApi.md @@ -729,7 +729,7 @@ public class Example { String enumQueryString = "_abc"; // String | Query parameter enum test (string) Integer enumQueryInteger = 1; // Integer | Query parameter enum test (double) Double enumQueryDouble = 1.1D; // Double | Query parameter enum test (double) - List enumFormStringArray = ">"; // List | Form parameter enum test (string array) + List enumFormStringArray = Arrays.asList("$"); // List | Form parameter enum test (string array) String enumFormString = "_abc"; // String | Form parameter enum test (string) try { apiInstance.testEnumParameters(enumHeaderStringArray, enumHeaderString, enumQueryStringArray, enumQueryString, enumQueryInteger, enumQueryDouble, enumFormStringArray, enumFormString); diff --git a/samples/openapi3/client/petstore/python/docs/FakeApi.md b/samples/openapi3/client/petstore/python/docs/FakeApi.md index 779400df320..6ee1a7c20a7 100644 --- a/samples/openapi3/client/petstore/python/docs/FakeApi.md +++ b/samples/openapi3/client/petstore/python/docs/FakeApi.md @@ -333,7 +333,7 @@ configuration = petstore_api.Configuration( with petstore_api.ApiClient() as api_client: # Create an instance of the API class api_instance = fake_api.FakeApi(api_client) - composed_one_of_number_with_validations = ComposedOneOfNumberWithValidations() # ComposedOneOfNumberWithValidations | Input model (optional) + composed_one_of_number_with_validations = ComposedOneOfNumberWithValidations(None) # ComposedOneOfNumberWithValidations | Input model (optional) # example passing only required values which don't have defaults set # and optional values @@ -609,11 +609,7 @@ configuration = petstore_api.Configuration( with petstore_api.ApiClient() as api_client: # Create an instance of the API class api_instance = fake_api.FakeApi(api_client) - mammal = Mammal( - has_baleen=True, - has_teeth=True, - class_name="whale", - ) # Mammal | Input mammal + mammal = Mammal(None) # Mammal | Input mammal # example passing only required values which don't have defaults set try: @@ -1437,7 +1433,9 @@ with petstore_api.ApiClient() as api_client: enum_query_string = "-efg" # str | Query parameter enum test (string) (optional) if omitted the server will use the default value of "-efg" enum_query_integer = 1 # int | Query parameter enum test (double) (optional) enum_query_double = 1.1 # float | Query parameter enum test (double) (optional) - enum_form_string_array = "$" # [str] | Form parameter enum test (string array) (optional) if omitted the server will use the default value of "$" + enum_form_string_array = [ + "$", + ] # [str] | Form parameter enum test (string array) (optional) if omitted the server will use the default value of "$" enum_form_string = "-efg" # str | Form parameter enum test (string) (optional) if omitted the server will use the default value of "-efg" # example passing only required values which don't have defaults set @@ -1956,7 +1954,9 @@ configuration = petstore_api.Configuration( with petstore_api.ApiClient() as api_client: # Create an instance of the API class api_instance = fake_api.FakeApi(api_client) - files = open('/path/to/file', 'rb') # [file_type] | (optional) + files = [ + open('/path/to/file', 'rb'), + ] # [file_type] | (optional) # example passing only required values which don't have defaults set # and optional values diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/DefaultApi.md b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/DefaultApi.md index a9df332ad47..d0c51705905 100644 --- a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/DefaultApi.md +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/DefaultApi.md @@ -26,7 +26,7 @@ const apiInstance = new .DefaultApi(configuration); let body:.DefaultApiFilePostRequest = { // InlineObject (optional) inlineObject: { - file: , + file: null, }, }; @@ -80,7 +80,7 @@ const apiInstance = new .DefaultApi(configuration); let body:.DefaultApiPetsFilteredPatchRequest = { // PetByAge | PetByType (optional) - petByAgePetByType: , + petByAgePetByType: null, }; apiInstance.petsFilteredPatch(body).then((data:any) => { @@ -133,7 +133,7 @@ const apiInstance = new .DefaultApi(configuration); let body:.DefaultApiPetsPatchRequest = { // Cat | Dog (optional) - catDog: , + catDog: null, }; apiInstance.petsPatch(body).then((data:any) => {