Skip to content

Commit f76d72e

Browse files
wing328stcarrez
andauthored
[BUG][Ada] Incorrect client Ada code generated (#7719)
* Fix #7594: [BUG][Ada] Incorrect client Ada code generated - Fix the identification of path parameters - Fix the model and client to support FreeFormObject * update doc * fix errors, update samples Co-authored-by: Stephane Carrez <Stephane.Carrez@gmail.com>
1 parent 53eb671 commit f76d72e

File tree

10 files changed

+228
-114
lines changed

10 files changed

+228
-114
lines changed

docs/generators/ada-server.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@ These options may be applied as additional-properties (cli) or configOptions (pl
3131
## LANGUAGE PRIMITIVES
3232

3333
<ul class="column-ul">
34-
<li>Boolean</li>
35-
<li>Character</li>
36-
<li>Integer</li>
34+
<li>DateTime</li>
35+
<li>binary</li>
3736
<li>boolean</li>
37+
<li>date</li>
3838
<li>double</li>
3939
<li>float</li>
4040
<li>integer</li>
4141
<li>long</li>
42+
<li>number</li>
43+
<li>object</li>
44+
<li>string</li>
4245
</ul>
4346

4447
## RESERVED WORDS
@@ -210,8 +213,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
210213
### Security Feature
211214
| Name | Supported | Defined By |
212215
| ---- | --------- | ---------- |
213-
|BasicAuth||OAS2,OAS3
214-
|ApiKey||OAS2,OAS3
216+
|BasicAuth||OAS2,OAS3
217+
|ApiKey||OAS2,OAS3
215218
|OpenIDConnect|✗|OAS3
216219
|BearerToken|✗|OAS3
217220
|OAuth2_Implicit|✗|OAS2,OAS3

docs/generators/ada.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@ These options may be applied as additional-properties (cli) or configOptions (pl
3131
## LANGUAGE PRIMITIVES
3232

3333
<ul class="column-ul">
34-
<li>Boolean</li>
35-
<li>Character</li>
36-
<li>Integer</li>
34+
<li>DateTime</li>
35+
<li>binary</li>
3736
<li>boolean</li>
37+
<li>date</li>
3838
<li>double</li>
3939
<li>float</li>
4040
<li>integer</li>
4141
<li>long</li>
42+
<li>number</li>
43+
<li>object</li>
44+
<li>string</li>
4245
</ul>
4346

4447
## RESERVED WORDS
@@ -124,7 +127,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
124127
### Client Modification Feature
125128
| Name | Supported | Defined By |
126129
| ---- | --------- | ---------- |
127-
|BasePath||ToolingExtension
130+
|BasePath||ToolingExtension
128131
|Authorizations|✗|ToolingExtension
129132
|UserAgent|✗|ToolingExtension
130133
|MockServer|✗|ToolingExtension
@@ -165,7 +168,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
165168
### Documentation Feature
166169
| Name | Supported | Defined By |
167170
| ---- | --------- | ---------- |
168-
|Readme||ToolingExtension
171+
|Readme||ToolingExtension
169172
|Model|✓|ToolingExtension
170173
|Api|✓|ToolingExtension
171174

@@ -185,7 +188,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
185188
|MultiServer|✗|OAS3
186189
|ParameterizedServer|✗|OAS3
187190
|ParameterStyling|✗|OAS3
188-
|Callbacks||OAS3
191+
|Callbacks||OAS3
189192
|LinkObjects|✗|OAS3
190193

191194
### Parameter Feature
@@ -204,20 +207,20 @@ These options may be applied as additional-properties (cli) or configOptions (pl
204207
| ---- | --------- | ---------- |
205208
|Simple|✓|OAS2,OAS3
206209
|Composite|✓|OAS2,OAS3
207-
|Polymorphism||OAS2,OAS3
210+
|Polymorphism||OAS2,OAS3
208211
|Union|✗|OAS3
209212

210213
### Security Feature
211214
| Name | Supported | Defined By |
212215
| ---- | --------- | ---------- |
213-
|BasicAuth||OAS2,OAS3
214-
|ApiKey||OAS2,OAS3
216+
|BasicAuth||OAS2,OAS3
217+
|ApiKey||OAS2,OAS3
215218
|OpenIDConnect|✗|OAS3
216-
|BearerToken||OAS3
217-
|OAuth2_Implicit||OAS2,OAS3
218-
|OAuth2_Password||OAS2,OAS3
219-
|OAuth2_ClientCredentials||OAS2,OAS3
220-
|OAuth2_AuthorizationCode||OAS2,OAS3
219+
|BearerToken||OAS3
220+
|OAuth2_Implicit||OAS2,OAS3
221+
|OAuth2_Password||OAS2,OAS3
222+
|OAuth2_ClientCredentials||OAS2,OAS3
223+
|OAuth2_AuthorizationCode||OAS2,OAS3
221224

222225
### Wire Format Feature
223226
| Name | Supported | Defined By |

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractAdaCodegen.java

Lines changed: 116 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
import io.swagger.v3.oas.models.servers.Server;
2929
import org.apache.commons.lang3.StringUtils;
3030
import org.openapitools.codegen.*;
31+
import org.openapitools.codegen.meta.features.ClientModificationFeature;
32+
import org.openapitools.codegen.meta.features.DocumentationFeature;
33+
import org.openapitools.codegen.meta.features.GlobalFeature;
34+
import org.openapitools.codegen.meta.features.SchemaSupportFeature;
35+
import org.openapitools.codegen.meta.features.SecurityFeature;
36+
import org.openapitools.codegen.meta.features.WireFormatFeature;
3137
import org.openapitools.codegen.utils.ModelUtils;
3238
import org.slf4j.Logger;
3339
import org.slf4j.LoggerFactory;
@@ -50,6 +56,26 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
5056
public AbstractAdaCodegen() {
5157
super();
5258

59+
modifyFeatureSet(features -> features
60+
.includeDocumentationFeatures(DocumentationFeature.Readme)
61+
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML))
62+
.securityFeatures(EnumSet.noneOf(
63+
SecurityFeature.class
64+
))
65+
.excludeGlobalFeatures(
66+
GlobalFeature.XMLStructureDefinitions,
67+
GlobalFeature.Callbacks,
68+
GlobalFeature.LinkObjects,
69+
GlobalFeature.ParameterStyling
70+
)
71+
.excludeSchemaSupportFeatures(
72+
SchemaSupportFeature.Polymorphism
73+
)
74+
.includeClientModificationFeatures(
75+
ClientModificationFeature.BasePath
76+
)
77+
);
78+
5379
/*
5480
* Reserved words. Override this with reserved words specific to your language
5581
*/
@@ -168,7 +194,8 @@ public AbstractAdaCodegen() {
168194
embeddedTemplateDir = templateDir = "Ada";
169195

170196
languageSpecificPrimitives = new HashSet<String>(
171-
Arrays.asList("integer", "boolean", "Integer", "Character", "Boolean", "long", "float", "double"));
197+
Arrays.asList("integer", "boolean", "number", "long", "float",
198+
"double", "object", "string", "date", "DateTime", "binary"));
172199
}
173200

174201
public String toFilename(String name) {
@@ -198,20 +225,28 @@ protected String toAdaIdentifier(String name, String prefix) {
198225
}
199226
StringBuilder result = new StringBuilder();
200227
boolean needUpperCase = true;
228+
boolean prevUpperCase = false;
229+
if (name.isEmpty() || Character.isDigit(name.charAt(0)) || name.charAt(0) == '_') {
230+
result.append(prefix);
231+
}
201232
for (int i = 0; i < name.length(); i++) {
202233
char c = name.charAt(i);
234+
boolean isUpperOrDigit = Character.isUpperCase(c) || Character.isDigit(c);
203235
if (needUpperCase) {
204236
needUpperCase = false;
237+
prevUpperCase = isUpperOrDigit;
205238
result.append(Character.toUpperCase(c));
206239

207-
} else if (Character.isUpperCase((c))) {
208-
if (!needUpperCase) {
240+
} else if (isUpperOrDigit) {
241+
if (!prevUpperCase) {
209242
result.append('_');
210243
}
211244
result.append(c);
212245
needUpperCase = false;
246+
prevUpperCase = true;
213247
} else {
214248
result.append(c);
249+
prevUpperCase = isUpperOrDigit;
215250
if (c == '_') {
216251
needUpperCase = true;
217252
}
@@ -276,6 +311,40 @@ public String toModelName(final String name) {
276311
return result;
277312
}
278313

314+
@Override
315+
public String toEnumVarName(String value, String datatype) {
316+
String var = null;
317+
if (value.isEmpty()) {
318+
var = "EMPTY";
319+
}
320+
321+
// for symbol, e.g. $, #
322+
else if (getSymbolName(value) != null) {
323+
var = getSymbolName(value).toUpperCase(Locale.ROOT);
324+
}
325+
326+
// number
327+
else if ("Integer".equals(datatype) || "Long".equals(datatype) ||
328+
"Float".equals(datatype) || "Double".equals(datatype)) {
329+
String varName = "NUMBER_" + value;
330+
varName = varName.replaceAll("-", "MINUS_");
331+
varName = varName.replaceAll("\\+", "PLUS_");
332+
varName = varName.replaceAll("\\.", "_DOT_");
333+
var = varName;
334+
}
335+
336+
// string
337+
else {
338+
var = value.replaceAll("\\W+", "_").toUpperCase(Locale.ROOT);
339+
if (var.matches("\\d.*")) {
340+
var = "_" + var;
341+
} else {
342+
var = sanitizeName(var);
343+
}
344+
}
345+
return var;
346+
}
347+
279348
@Override
280349
public CodegenProperty fromProperty(String name, Schema p) {
281350
CodegenProperty property = super.fromProperty(name, p);
@@ -371,6 +440,44 @@ public String getTypeDeclaration(Schema p) {
371440
return modelPackage + ".Models." + modelType;
372441
}
373442

443+
private boolean isStreamType(CodegenProperty parameter) {
444+
boolean isStreamType = parameter.isString || parameter.isBoolean || parameter.isDate
445+
|| parameter.isDateTime || parameter.isInteger || parameter.isLong
446+
|| (parameter.isFreeFormObject && !parameter.isMap);
447+
448+
return isStreamType;
449+
}
450+
451+
private boolean isModelType(CodegenProperty parameter) {
452+
boolean isModel = parameter.dataType.startsWith(modelPackage);
453+
if (!isModel && !parameter.isPrimitiveType && !parameter.isDate
454+
&& !parameter.isFreeFormObject
455+
&& !parameter.isString && !parameter.isContainer && !parameter.isFile
456+
&& !parameter.dataType.startsWith("Swagger")) {
457+
isModel = true;
458+
}
459+
return isModel;
460+
}
461+
462+
private boolean isStreamType(CodegenParameter parameter) {
463+
boolean isStreamType = parameter.isString || parameter.isBoolean || parameter.isDate
464+
|| parameter.isDateTime || parameter.isInteger || parameter.isLong
465+
|| (parameter.isFreeFormObject && !parameter.isMap);
466+
467+
return isStreamType;
468+
}
469+
470+
private boolean isModelType(CodegenParameter parameter) {
471+
boolean isModel = parameter.dataType.startsWith(modelPackage);
472+
if (!isModel && !parameter.isPrimitiveType && !parameter.isDate
473+
&& !parameter.isFreeFormObject
474+
&& !parameter.isString && !parameter.isContainer && !parameter.isFile
475+
&& !parameter.dataType.startsWith("Swagger")) {
476+
isModel = true;
477+
}
478+
return isModel;
479+
}
480+
374481
/**
375482
* Overrides postProcessParameter to add a vendor extension "x-is-model-type".
376483
* This boolean indicates that the parameter comes from the model package.
@@ -385,12 +492,8 @@ public void postProcessParameter(CodegenParameter parameter) {
385492
if (parameter.dataType == null) {
386493
return;
387494
}
388-
boolean isModel = parameter.dataType.startsWith(modelPackage);
389-
if (!isModel && !parameter.isPrimitiveType && !parameter.isDate
390-
&& !parameter.isString && !parameter.isContainer && !parameter.isFile) {
391-
isModel = true;
392-
}
393-
parameter.vendorExtensions.put("x-is-model-type", isModel);
495+
parameter.vendorExtensions.put("x-is-model-type", isModelType(parameter));
496+
parameter.vendorExtensions.put("x-is-stream-type", isStreamType(parameter));
394497
}
395498

396499
/**
@@ -426,6 +529,8 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
426529
if (methodResponse != null && ModelUtils.getSchemaFromResponse(methodResponse) != null) {
427530
CodegenProperty cm = fromProperty("response", ModelUtils.getSchemaFromResponse(methodResponse));
428531
op.vendorExtensions.put("x-codegen-response", cm);
532+
op.vendorExtensions.put("x-is-model-type", isModelType(cm));
533+
op.vendorExtensions.put("x-is-stream-type", isStreamType(cm));
429534
if ("HttpContent".equals(cm.dataType)) {
430535
op.vendorExtensions.put("x-codegen-response-ishttpcontent", true);
431536
}
@@ -524,7 +629,7 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
524629
if (last < 0) {
525630
break;
526631
}
527-
if (path.substring(pos, last - 1).equals(p.baseName)) {
632+
if (path.substring(pos, last).equals(p.baseName)) {
528633
break;
529634
}
530635
pos = last + 1;
@@ -558,6 +663,7 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
558663
isModel = true;
559664
}
560665
p.vendorExtensions.put("x-is-model-type", isModel);
666+
p.vendorExtensions.put("x-is-stream-type", isStreamType(p));
561667
Boolean required = p.getRequired();
562668

563669
// Convert optional members to use the Nullable_<T> type.

modules/openapi-generator/src/main/resources/Ada/client-body.mustache

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,15 @@ package body {{package}}.Clients is
3939
URI.Add_Param ("{{baseName}}", {{paramName}});{{/isDateTime}}{{/isQueryParam}}{{/queryParams}}
4040
URI.Set_Path ("{{path}}");{{#pathParams}}
4141
URI.Set_Path_Param ("{{baseName}}", {{^isString}}Swagger.To_String ({{/isString}}{{paramName}}{{^isString}}){{/isString}});{{/pathParams}}
42-
Client.Call (Swagger.Clients.{{httpMethod}}, URI{{#hasBodyParam}}, Req{{/hasBodyParam}}{{#hasFormParams}}, Req{{/hasFormParams}}{{#returnType}}, Reply{{/returnType}});{{#returnType}}{{#vendorExtensions.x-codegen-response.isString}}
43-
Swagger.Streams.Deserialize (Reply, "", Result);{{/vendorExtensions.x-codegen-response.isString}}{{^vendorExtensions.x-codegen-response.isString}}{{#returnTypeIsPrimitive}}
44-
Swagger.Streams.Deserialize (Reply, "", Result);{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}
45-
{{package}}.Models.Deserialize (Reply, "", Result);{{/returnTypeIsPrimitive}}{{/vendorExtensions.x-codegen-response.isString}}{{/returnType}}
42+
Client.Call (Swagger.Clients.{{httpMethod}}, URI{{#hasBodyParam}}, Req{{/hasBodyParam}}{{#hasFormParams}}, Req{{/hasFormParams}}{{#returnType}}, Reply{{/returnType}});
43+
{{#returnType}}
44+
{{^vendorExtensions.x-is-model-type}}
45+
Swagger.Streams.Deserialize (Reply, "", Result);
46+
{{/vendorExtensions.x-is-model-type}}
47+
{{#vendorExtensions.x-is-model-type}}
48+
{{package}}.Models.Deserialize (Reply, "", Result);
49+
{{/vendorExtensions.x-is-model-type}}
50+
{{/returnType}}
4651
end {{operationId}};
4752
{{/operation}}
4853
{{/operations}}

modules/openapi-generator/src/main/resources/Ada/model-body.mustache

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,10 @@ package body {{package}}.Models is
1111
Name : in String;
1212
Value : in {{classname}}) is
1313
begin
14-
Into.Start_Entity (Name);{{#vars}}{{^isPrimitiveType}}{{^isString}}{{^isContainer}}{{^isDateTime}}
15-
Serialize (Into, "{{baseName}}", Value.{{name}});{{/isDateTime}}{{/isContainer}}{{/isString}}{{/isPrimitiveType}}{{#isPrimitiveType}}{{^isLong}}
16-
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isLong}}{{/isPrimitiveType}}{{#isLong}}
17-
Serialize (Into, "{{baseName}}", Value.{{name}});{{/isLong}}{{#isString}}
18-
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isString}}{{#isContainer}}
19-
Serialize (Into, "{{baseName}}", Value.{{name}});{{/isContainer}}{{#isDateTime}}
20-
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isDateTime}}{{/vars}}
14+
Into.Start_Entity (Name);{{#vars}}{{#vendorExtensions.x-is-stream-type}}{{^isLong}}
15+
Into.Write_Entity ("{{baseName}}", Value.{{name}});{{/isLong}}{{#isLong}}
16+
Into.Write_Long_Entity ("{{baseName}}", Value.{{name}});{{/isLong}}{{/vendorExtensions.x-is-stream-type}}{{^vendorExtensions.x-is-stream-type}}
17+
Serialize (Into, "{{baseName}}", Value.{{name}});{{/vendorExtensions.x-is-stream-type}}{{/vars}}
2118
Into.End_Entity (Name);
2219
end Serialize;
2320

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.2.3-SNAPSHOT
1+
5.0.0-SNAPSHOT

samples/client/petstore/ada/src/client/samples-petstore-clients.adb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
-- The version of the OpenAPI document: 1.0.0
55
--
66
--
7-
-- NOTE: This package is auto generated by OpenAPI-Generator 4.2.3-SNAPSHOT.
7+
-- NOTE: This package is auto generated by OpenAPI-Generator 5.0.0-SNAPSHOT.
88
-- https://openapi-generator.tech
99
-- Do not edit the class manually.
1010

samples/client/petstore/ada/src/client/samples-petstore-clients.ads

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
-- The version of the OpenAPI document: 1.0.0
55
--
66
--
7-
-- NOTE: This package is auto generated by OpenAPI-Generator 4.2.3-SNAPSHOT.
7+
-- NOTE: This package is auto generated by OpenAPI-Generator 5.0.0-SNAPSHOT.
88
-- https://openapi-generator.tech
99
-- Do not edit the class manually.
1010

0 commit comments

Comments
 (0)