Skip to content

[BUG][Ada] Incorrect client Ada code generated #7719

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions docs/generators/ada-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Boolean</li>
<li>Character</li>
<li>Integer</li>
<li>DateTime</li>
<li>binary</li>
<li>boolean</li>
<li>date</li>
<li>double</li>
<li>float</li>
<li>integer</li>
<li>long</li>
<li>number</li>
<li>object</li>
<li>string</li>
</ul>

## RESERVED WORDS
Expand Down Expand Up @@ -210,8 +213,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth||OAS2,OAS3
|ApiKey||OAS2,OAS3
|BasicAuth||OAS2,OAS3
|ApiKey||OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✗|OAS3
|OAuth2_Implicit|✗|OAS2,OAS3
Expand Down
31 changes: 17 additions & 14 deletions docs/generators/ada.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,17 @@ These options may be applied as additional-properties (cli) or configOptions (pl
## LANGUAGE PRIMITIVES

<ul class="column-ul">
<li>Boolean</li>
<li>Character</li>
<li>Integer</li>
<li>DateTime</li>
<li>binary</li>
<li>boolean</li>
<li>date</li>
<li>double</li>
<li>float</li>
<li>integer</li>
<li>long</li>
<li>number</li>
<li>object</li>
<li>string</li>
</ul>

## RESERVED WORDS
Expand Down Expand Up @@ -124,7 +127,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath||ToolingExtension
|BasePath||ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
Expand Down Expand Up @@ -165,7 +168,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme||ToolingExtension
|Readme||ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension

Expand All @@ -185,7 +188,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks||OAS3
|Callbacks||OAS3
|LinkObjects|✗|OAS3

### Parameter Feature
Expand All @@ -204,20 +207,20 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism||OAS2,OAS3
|Polymorphism||OAS2,OAS3
|Union|✗|OAS3

### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth||OAS2,OAS3
|ApiKey||OAS2,OAS3
|BasicAuth||OAS2,OAS3
|ApiKey||OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken||OAS3
|OAuth2_Implicit||OAS2,OAS3
|OAuth2_Password||OAS2,OAS3
|OAuth2_ClientCredentials||OAS2,OAS3
|OAuth2_AuthorizationCode||OAS2,OAS3
|BearerToken||OAS3
|OAuth2_Implicit||OAS2,OAS3
|OAuth2_Password||OAS2,OAS3
|OAuth2_ClientCredentials||OAS2,OAS3
|OAuth2_AuthorizationCode||OAS2,OAS3

### Wire Format Feature
| Name | Supported | Defined By |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
import io.swagger.v3.oas.models.servers.Server;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.ClientModificationFeature;
import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.openapitools.codegen.meta.features.GlobalFeature;
import org.openapitools.codegen.meta.features.SchemaSupportFeature;
import org.openapitools.codegen.meta.features.SecurityFeature;
import org.openapitools.codegen.meta.features.WireFormatFeature;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -50,6 +56,26 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
public AbstractAdaCodegen() {
super();

modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
.securityFeatures(EnumSet.noneOf(
SecurityFeature.class
))
.excludeGlobalFeatures(
GlobalFeature.XMLStructureDefinitions,
GlobalFeature.Callbacks,
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
.excludeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
)
.includeClientModificationFeatures(
ClientModificationFeature.BasePath
)
);

/*
* Reserved words. Override this with reserved words specific to your language
*/
Expand Down Expand Up @@ -168,7 +194,8 @@ public AbstractAdaCodegen() {
embeddedTemplateDir = templateDir = "Ada";

languageSpecificPrimitives = new HashSet<String>(
Arrays.asList("integer", "boolean", "Integer", "Character", "Boolean", "long", "float", "double"));
Arrays.asList("integer", "boolean", "number", "long", "float",
"double", "object", "string", "date", "DateTime", "binary"));
}

public String toFilename(String name) {
Expand Down Expand Up @@ -198,20 +225,28 @@ protected String toAdaIdentifier(String name, String prefix) {
}
StringBuilder result = new StringBuilder();
boolean needUpperCase = true;
boolean prevUpperCase = false;
if (name.isEmpty() || Character.isDigit(name.charAt(0)) || name.charAt(0) == '_') {
result.append(prefix);
}
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
boolean isUpperOrDigit = Character.isUpperCase(c) || Character.isDigit(c);
if (needUpperCase) {
needUpperCase = false;
prevUpperCase = isUpperOrDigit;
result.append(Character.toUpperCase(c));

} else if (Character.isUpperCase((c))) {
if (!needUpperCase) {
} else if (isUpperOrDigit) {
if (!prevUpperCase) {
result.append('_');
}
result.append(c);
needUpperCase = false;
prevUpperCase = true;
} else {
result.append(c);
prevUpperCase = isUpperOrDigit;
if (c == '_') {
needUpperCase = true;
}
Expand Down Expand Up @@ -276,6 +311,40 @@ public String toModelName(final String name) {
return result;
}

@Override
public String toEnumVarName(String value, String datatype) {
String var = null;
if (value.isEmpty()) {
var = "EMPTY";
}

// for symbol, e.g. $, #
else if (getSymbolName(value) != null) {
var = getSymbolName(value).toUpperCase(Locale.ROOT);
}

// number
else if ("Integer".equals(datatype) || "Long".equals(datatype) ||
"Float".equals(datatype) || "Double".equals(datatype)) {
String varName = "NUMBER_" + value;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
var = varName;
}

// string
else {
var = value.replaceAll("\\W+", "_").toUpperCase(Locale.ROOT);
if (var.matches("\\d.*")) {
var = "_" + var;
} else {
var = sanitizeName(var);
}
}
return var;
}

@Override
public CodegenProperty fromProperty(String name, Schema p) {
CodegenProperty property = super.fromProperty(name, p);
Expand Down Expand Up @@ -371,6 +440,44 @@ public String getTypeDeclaration(Schema p) {
return modelPackage + ".Models." + modelType;
}

private boolean isStreamType(CodegenProperty parameter) {
boolean isStreamType = parameter.isString || parameter.isBoolean || parameter.isDate
|| parameter.isDateTime || parameter.isInteger || parameter.isLong
|| (parameter.isFreeFormObject && !parameter.isMap);

return isStreamType;
}

private boolean isModelType(CodegenProperty parameter) {
boolean isModel = parameter.dataType.startsWith(modelPackage);
if (!isModel && !parameter.isPrimitiveType && !parameter.isDate
&& !parameter.isFreeFormObject
&& !parameter.isString && !parameter.isContainer && !parameter.isFile
&& !parameter.dataType.startsWith("Swagger")) {
isModel = true;
}
return isModel;
}

private boolean isStreamType(CodegenParameter parameter) {
boolean isStreamType = parameter.isString || parameter.isBoolean || parameter.isDate
|| parameter.isDateTime || parameter.isInteger || parameter.isLong
|| (parameter.isFreeFormObject && !parameter.isMap);

return isStreamType;
}

private boolean isModelType(CodegenParameter parameter) {
boolean isModel = parameter.dataType.startsWith(modelPackage);
if (!isModel && !parameter.isPrimitiveType && !parameter.isDate
&& !parameter.isFreeFormObject
&& !parameter.isString && !parameter.isContainer && !parameter.isFile
&& !parameter.dataType.startsWith("Swagger")) {
isModel = true;
}
return isModel;
}

/**
* Overrides postProcessParameter to add a vendor extension "x-is-model-type".
* This boolean indicates that the parameter comes from the model package.
Expand All @@ -385,12 +492,8 @@ public void postProcessParameter(CodegenParameter parameter) {
if (parameter.dataType == null) {
return;
}
boolean isModel = parameter.dataType.startsWith(modelPackage);
if (!isModel && !parameter.isPrimitiveType && !parameter.isDate
&& !parameter.isString && !parameter.isContainer && !parameter.isFile) {
isModel = true;
}
parameter.vendorExtensions.put("x-is-model-type", isModel);
parameter.vendorExtensions.put("x-is-model-type", isModelType(parameter));
parameter.vendorExtensions.put("x-is-stream-type", isStreamType(parameter));
}

/**
Expand Down Expand Up @@ -426,6 +529,8 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
if (methodResponse != null && ModelUtils.getSchemaFromResponse(methodResponse) != null) {
CodegenProperty cm = fromProperty("response", ModelUtils.getSchemaFromResponse(methodResponse));
op.vendorExtensions.put("x-codegen-response", cm);
op.vendorExtensions.put("x-is-model-type", isModelType(cm));
op.vendorExtensions.put("x-is-stream-type", isStreamType(cm));
if ("HttpContent".equals(cm.dataType)) {
op.vendorExtensions.put("x-codegen-response-ishttpcontent", true);
}
Expand Down Expand Up @@ -524,7 +629,7 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
if (last < 0) {
break;
}
if (path.substring(pos, last - 1).equals(p.baseName)) {
if (path.substring(pos, last).equals(p.baseName)) {
break;
}
pos = last + 1;
Expand Down Expand Up @@ -558,6 +663,7 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
isModel = true;
}
p.vendorExtensions.put("x-is-model-type", isModel);
p.vendorExtensions.put("x-is-stream-type", isStreamType(p));
Boolean required = p.getRequired();

// Convert optional members to use the Nullable_<T> type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,15 @@ package body {{package}}.Clients is
URI.Add_Param ("{{baseName}}", {{paramName}});{{/isDateTime}}{{/isQueryParam}}{{/queryParams}}
URI.Set_Path ("{{path}}");{{#pathParams}}
URI.Set_Path_Param ("{{baseName}}", {{^isString}}Swagger.To_String ({{/isString}}{{paramName}}{{^isString}}){{/isString}});{{/pathParams}}
Client.Call (Swagger.Clients.{{httpMethod}}, URI{{#hasBodyParam}}, Req{{/hasBodyParam}}{{#hasFormParams}}, Req{{/hasFormParams}}{{#returnType}}, Reply{{/returnType}});{{#returnType}}{{#vendorExtensions.x-codegen-response.isString}}
Swagger.Streams.Deserialize (Reply, "", Result);{{/vendorExtensions.x-codegen-response.isString}}{{^vendorExtensions.x-codegen-response.isString}}{{#returnTypeIsPrimitive}}
Swagger.Streams.Deserialize (Reply, "", Result);{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}
{{package}}.Models.Deserialize (Reply, "", Result);{{/returnTypeIsPrimitive}}{{/vendorExtensions.x-codegen-response.isString}}{{/returnType}}
Client.Call (Swagger.Clients.{{httpMethod}}, URI{{#hasBodyParam}}, Req{{/hasBodyParam}}{{#hasFormParams}}, Req{{/hasFormParams}}{{#returnType}}, Reply{{/returnType}});
{{#returnType}}
{{^vendorExtensions.x-is-model-type}}
Swagger.Streams.Deserialize (Reply, "", Result);
{{/vendorExtensions.x-is-model-type}}
{{#vendorExtensions.x-is-model-type}}
{{package}}.Models.Deserialize (Reply, "", Result);
{{/vendorExtensions.x-is-model-type}}
{{/returnType}}
end {{operationId}};
{{/operation}}
{{/operations}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@ package body {{package}}.Models is
Name : in String;
Value : in {{classname}}) is
begin
Into.Start_Entity (Name);{{#vars}}{{^isPrimitiveType}}{{^isString}}{{^isContainer}}{{^isDateTime}}
Serialize (Into, "{{baseName}}", Value.{{name}});{{/isDateTime}}{{/isContainer}}{{/isString}}{{/isPrimitiveType}}{{#isPrimitiveType}}{{^isLong}}
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isLong}}{{/isPrimitiveType}}{{#isLong}}
Serialize (Into, "{{baseName}}", Value.{{name}});{{/isLong}}{{#isString}}
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isString}}{{#isContainer}}
Serialize (Into, "{{baseName}}", Value.{{name}});{{/isContainer}}{{#isDateTime}}
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isDateTime}}{{/vars}}
Into.Start_Entity (Name);{{#vars}}{{#vendorExtensions.x-is-stream-type}}{{^isLong}}
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isLong}}{{#isLong}}
Into.Write_Long_Entity ("{{baseName}}", Value.{{name}});{{/isLong}}{{/vendorExtensions.x-is-stream-type}}{{^vendorExtensions.x-is-stream-type}}
Serialize (Into, "{{baseName}}", Value.{{name}});{{/vendorExtensions.x-is-stream-type}}{{/vars}}
Into.End_Entity (Name);
end Serialize;

Expand Down
2 changes: 1 addition & 1 deletion samples/client/petstore/ada/.openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.2.3-SNAPSHOT
5.0.0-SNAPSHOT
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-- The version of the OpenAPI document: 1.0.0
--
--
-- NOTE: This package is auto generated by OpenAPI-Generator 4.2.3-SNAPSHOT.
-- NOTE: This package is auto generated by OpenAPI-Generator 5.0.0-SNAPSHOT.
-- https://openapi-generator.tech
-- Do not edit the class manually.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-- The version of the OpenAPI document: 1.0.0
--
--
-- NOTE: This package is auto generated by OpenAPI-Generator 4.2.3-SNAPSHOT.
-- NOTE: This package is auto generated by OpenAPI-Generator 5.0.0-SNAPSHOT.
-- https://openapi-generator.tech
-- Do not edit the class manually.

Expand Down
Loading