Skip to content

Commit 777031f

Browse files
authored
Fix a few issues with go examples generation (#7873)
* Fix a few issues with go examples generation This fixes a bunch of issues seen when generating go examples, namely - Numbers aren't casted to the right type - The time import is missing - Enums are treated as regular models * Rebuild more samples * Use examples properly * Handle multiple instances in the same doc * Fix wrong array closure * Handle model arrays * Fix file and enum namespace * Regenerate samples * Handle maps of complex types * Handle oneOf * Fix padding * Fix enum doc * Removes links to basic types in arrays * Remove links to basic types in maps * Fix enum links * Minor indent fix * Handle review comments
1 parent 3b84e8b commit 777031f

File tree

18 files changed

+194
-122
lines changed

18 files changed

+194
-122
lines changed

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

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -448,26 +448,44 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
448448
for (CodegenParameter p : op.allParams) {
449449
p.vendorExtensions.put("x-go-example", constructExampleCode(p, modelMaps, processedModelMaps));
450450
}
451+
processedModelMaps.clear();
451452
}
452453

453-
processedModelMaps.clear();
454454
for (CodegenOperation operation : operationList) {
455+
boolean needTimeImport = false;
455456
for (CodegenParameter cp : operation.allParams) {
456457
cp.vendorExtensions.put("x-go-example", constructExampleCode(cp, modelMaps, processedModelMaps));
458+
if (cp.isDateTime || cp.isDate) { // datetime or date
459+
needTimeImport = true;
460+
}
461+
}
462+
if (needTimeImport) {
463+
operation.vendorExtensions.put("x-go-import", " \"time\"");
457464
}
465+
processedModelMaps.clear();
458466
}
459467

460468
return objs;
461469
}
462470

463471
private String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps, HashMap<String, Integer> processedModelMap) {
464472
if (codegenParameter.isArray) { // array
465-
return codegenParameter.dataType + "{" + constructExampleCode(codegenParameter.items, modelMaps, processedModelMap) + "}";
473+
String prefix = codegenParameter.dataType;
474+
String dataType = StringUtils.removeStart(codegenParameter.dataType, "[]");
475+
if (modelMaps.containsKey(dataType)) {
476+
prefix = "[]" + goImportAlias + "." + dataType;
477+
}
478+
return prefix + "{" + constructExampleCode(codegenParameter.items, modelMaps, processedModelMap) + "}";
466479
} else if (codegenParameter.isMap) {
467-
return codegenParameter.dataType + "{ \"key\": " + constructExampleCode(codegenParameter.items, modelMaps, processedModelMap) + "}";
480+
String prefix = codegenParameter.dataType;
481+
String dataType = StringUtils.removeStart(codegenParameter.dataType, "map[string][]");
482+
if (modelMaps.containsKey(dataType)) {
483+
prefix = "map[string][]" + goImportAlias + "." + dataType;
484+
}
485+
return prefix + "{\"key\": " + constructExampleCode(codegenParameter.items, modelMaps, processedModelMap) + "}";
468486
} else if (codegenParameter.isPrimitiveType) { // primitive type
469487
if (codegenParameter.isString) {
470-
if (StringUtils.isEmpty(codegenParameter.example)) {
488+
if (!StringUtils.isEmpty(codegenParameter.example) && codegenParameter.example != "null") {
471489
return "\"" + codegenParameter.example + "\"";
472490
} else {
473491
return "\"" + codegenParameter.paramName + "_example\"";
@@ -482,11 +500,13 @@ private String constructExampleCode(CodegenParameter codegenParameter, HashMap<S
482500
return "\"https://example.com\"";
483501
} else if (codegenParameter.isDateTime || codegenParameter.isDate) { // datetime or date
484502
return "time.Now()";
503+
} else if (codegenParameter.isFile) {
504+
return "os.NewFile(1234, \"some_file\")";
485505
} else { // numeric
486-
if (StringUtils.isEmpty(codegenParameter.example)) {
487-
return codegenParameter.example;
506+
if (!StringUtils.isEmpty(codegenParameter.example) && codegenParameter.example != "null") {
507+
return codegenParameter.dataType + "(" + codegenParameter.example + ")";
488508
} else {
489-
return "987";
509+
return codegenParameter.dataType + "(987)";
490510
}
491511
}
492512
} else { // model
@@ -502,12 +522,22 @@ private String constructExampleCode(CodegenParameter codegenParameter, HashMap<S
502522

503523
private String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, HashMap<String, Integer> processedModelMap) {
504524
if (codegenProperty.isArray) { // array
505-
return codegenProperty.dataType + "{" + constructExampleCode(codegenProperty.items, modelMaps, processedModelMap) + ")";
525+
String prefix = codegenProperty.dataType;
526+
String dataType = StringUtils.removeStart(codegenProperty.dataType, "[]");
527+
if (modelMaps.containsKey(dataType)) {
528+
prefix = "[]" + goImportAlias + "." + dataType;
529+
}
530+
return prefix + "{" + constructExampleCode(codegenProperty.items, modelMaps, processedModelMap) + "}";
506531
} else if (codegenProperty.isMap) { // map
507-
return codegenProperty.dataType + "{ \"key\": " + constructExampleCode(codegenProperty.items, modelMaps, processedModelMap) + "}";
532+
String prefix = codegenProperty.dataType;
533+
String dataType = StringUtils.removeStart(codegenProperty.dataType, "map[string][]");
534+
if (modelMaps.containsKey(dataType)) {
535+
prefix = "map[string][]" + goImportAlias + "." + dataType;
536+
}
537+
return prefix + "{\"key\": " + constructExampleCode(codegenProperty.items, modelMaps, processedModelMap) + "}";
508538
} else if (codegenProperty.isPrimitiveType) { // primitive type
509539
if (codegenProperty.isString) {
510-
if (StringUtils.isEmpty(codegenProperty.example)) {
540+
if (!StringUtils.isEmpty(codegenProperty.example) && codegenProperty.example != "null") {
511541
return "\"" + codegenProperty.example + "\"";
512542
} else {
513543
return "\"" + codegenProperty.name + "_example\"";
@@ -524,17 +554,13 @@ private String constructExampleCode(CodegenProperty codegenProperty, HashMap<Str
524554
return "time.Now()";
525555
} else { // numeric
526556
String example;
527-
if (StringUtils.isEmpty(codegenProperty.example)) {
557+
if (!StringUtils.isEmpty(codegenProperty.example) && codegenProperty.example != "null") {
528558
example = codegenProperty.example;
529559
} else {
530560
example = "123";
531561
}
532562

533-
if (codegenProperty.isLong) {
534-
return "int64(" + example + ")";
535-
} else {
536-
return example;
537-
}
563+
return codegenProperty.dataType + "(" + example + ")";
538564
}
539565
} else {
540566
// look up the model
@@ -548,8 +574,6 @@ private String constructExampleCode(CodegenProperty codegenProperty, HashMap<Str
548574
}
549575

550576
private String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps, HashMap<String, Integer> processedModelMap) {
551-
String example;
552-
553577
// break infinite recursion. Return, in case a model is already processed in the current context.
554578
String model = codegenModel.name;
555579
if (processedModelMap.containsKey(model)) {
@@ -561,6 +585,14 @@ private String constructExampleCode(CodegenModel codegenModel, HashMap<String, C
561585
} else {
562586
throw new RuntimeException("Invalid count when constructing example: " + count);
563587
}
588+
} else if (codegenModel.isEnum) {
589+
Map<String, Object> allowableValues = codegenModel.allowableValues;
590+
List<Object> values = (List<Object>) allowableValues.get("values");
591+
return goImportAlias + "." + model + "(\"" + String.valueOf(values.get(0)) + "\")";
592+
} else if (codegenModel.oneOf != null && !codegenModel.oneOf.isEmpty()) {
593+
String subModel = (String) codegenModel.oneOf.toArray()[0];
594+
String oneOf = constructExampleCode(modelMaps.get(subModel), modelMaps, processedModelMap).substring(1);
595+
return goImportAlias + "." + model + "{" + subModel + ": " + oneOf + "}";
564596
} else {
565597
processedModelMap.put(model, 1);
566598
}
@@ -569,6 +601,6 @@ private String constructExampleCode(CodegenModel codegenModel, HashMap<String, C
569601
for (CodegenProperty codegenProperty : codegenModel.requiredVars) {
570602
propertyExamples.add(constructExampleCode(codegenProperty, modelMaps, processedModelMap));
571603
}
572-
return "*" + goImportAlias + ".New" + codegenModel.name + "(" + StringUtils.join(propertyExamples, ", ") + ")";
604+
return "*" + goImportAlias + ".New" + model + "(" + StringUtils.join(propertyExamples, ", ") + ")";
573605
}
574606
}

modules/openapi-generator/src/main/resources/go/api_doc.mustache

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import (
2929
"context"
3030
"fmt"
3131
"os"
32+
{{#vendorExtensions.x-go-import}}
33+
{{{vendorExtensions.x-go-import}}}
34+
{{/vendorExtensions.x-go-import}}
3235
{{goImportAlias}} "./openapi"
3336
)
3437

@@ -66,7 +69,7 @@ Other parameters are passed through a pointer to a api{{{nickname}}}Request stru
6669

6770
Name | Type | Description | Notes
6871
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}{{#allParams}}
69-
{{^isPathParam}} **{{paramName}}** | {{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{baseType}}.md){{/isFile}}{{/isPrimitiveType}} | {{description}} | {{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}{{/isPathParam}}{{/allParams}}
72+
{{^isPathParam}} **{{paramName}}** | {{#isContainer}}{{#isArray}}{{#items}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**[]{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isFile}}{{/isPrimitiveType}}{{/items}}{{/isArray}}{{#isMap}}{{#items}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**map[string]{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isFile}}{{/isPrimitiveType}}{{/items}}{{/isMap}}{{/isContainer}}{{^isContainer}}{{^isPrimitiveType}}{{^isFile}}[{{/isFile}}{{/isPrimitiveType}}**{{dataType}}**{{^isPrimitiveType}}{{^isFile}}]({{^baseType}}{{dataType}}{{/baseType}}{{#baseType}}{{baseType}}{{/baseType}}.md){{/isFile}}{{/isPrimitiveType}}{{/isContainer}} | {{description}} | {{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}{{/isPathParam}}{{/allParams}}
7073

7174
### Return type
7275

modules/openapi-generator/src/main/resources/go/model_doc.mustache

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{{#models}}{{#model}}# {{classname}}
22

3+
{{^isEnum}}
34
## Properties
45

56
Name | Type | Description | Notes
@@ -12,7 +13,6 @@ Name | Type | Description | Notes
1213
{{/vars}}
1314
{{/vendorExtensions.x-is-one-of-interface}}
1415

15-
{{^isEnum}}
1616
## Methods
1717

1818
{{^vendorExtensions.x-is-one-of-interface}}
@@ -84,6 +84,13 @@ Convenience method to wrap this instance of {{classname}} in {{{.}}}
8484
{{/vendorExtensions.x-implements}}
8585
{{/vendorExtensions.x-is-one-of-interface}}
8686
{{/isEnum}}
87+
{{#isEnum}}
88+
## Enum
89+
90+
{{#allowableValues}}{{#enumVars}}
91+
* `{{name}}` (value: `{{{value}}}`)
92+
{{/enumVars}}{{/allowableValues}}
93+
{{/isEnum}}
8794

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

samples/client/petstore/go/go-petstore/docs/EnumClass.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# EnumClass
22

3-
## Properties
3+
## Enum
44

5-
Name | Type | Description | Notes
6-
------------ | ------------- | ------------- | -------------
5+
6+
* `ABC` (value: `"_abc"`)
7+
8+
* `EFG` (value: `"-efg"`)
9+
10+
* `XYZ` (value: `"(xyz)"`)
711

812

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

samples/client/petstore/go/go-petstore/docs/FakeApi.md

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ import (
238238
)
239239

240240
func main() {
241-
body := 987 // float32 | Input number as post body (optional)
241+
body := float32(8.14) // float32 | Input number as post body (optional)
242242

243243
configuration := openapiclient.NewConfiguration()
244244
api_client := openapiclient.NewAPIClient(configuration)
@@ -560,20 +560,21 @@ import (
560560
"context"
561561
"fmt"
562562
"os"
563+
"time"
563564
openapiclient "./openapi"
564565
)
565566

566567
func main() {
567-
number := 987 // float32 | None
568-
double := 987 // float64 | None
568+
number := float32(8.14) // float32 | None
569+
double := float64(1.2) // float64 | None
569570
patternWithoutDelimiter := "patternWithoutDelimiter_example" // string | None
570-
byte_ := 987 // string | None
571-
integer := 987 // int32 | None (optional)
572-
int32_ := 987 // int32 | None (optional)
573-
int64_ := 987 // int64 | None (optional)
574-
float := 987 // float32 | None (optional)
571+
byte_ := string(BYTE_ARRAY_DATA_HERE) // string | None
572+
integer := int32(56) // int32 | None (optional)
573+
int32_ := int32(56) // int32 | None (optional)
574+
int64_ := int64(789) // int64 | None (optional)
575+
float := float32(3.4) // float32 | None (optional)
575576
string_ := "string__example" // string | None (optional)
576-
binary := 987 // *os.File | None (optional)
577+
binary := os.NewFile(1234, "some_file") // *os.File | None (optional)
577578
date := time.Now() // string | None (optional)
578579
dateTime := time.Now() // time.Time | None (optional)
579580
password := "password_example" // string | None (optional)
@@ -658,8 +659,8 @@ func main() {
658659
enumHeaderString := "enumHeaderString_example" // string | Header parameter enum test (string) (optional) (default to "-efg")
659660
enumQueryStringArray := []string{"EnumQueryStringArray_example"} // []string | Query parameter enum test (string array) (optional)
660661
enumQueryString := "enumQueryString_example" // string | Query parameter enum test (string) (optional) (default to "-efg")
661-
enumQueryInteger := 987 // int32 | Query parameter enum test (double) (optional)
662-
enumQueryDouble := 987 // float64 | Query parameter enum test (double) (optional)
662+
enumQueryInteger := int32(56) // int32 | Query parameter enum test (double) (optional)
663+
enumQueryDouble := float64(1.2) // float64 | Query parameter enum test (double) (optional)
663664
enumFormStringArray := []string{"Inner_example"} // []string | Form parameter enum test (string array) (optional) (default to "$")
664665
enumFormString := "enumFormString_example" // string | Form parameter enum test (string) (optional) (default to "-efg")
665666

@@ -684,13 +685,13 @@ Other parameters are passed through a pointer to a apiTestEnumParametersRequest
684685

685686
Name | Type | Description | Notes
686687
------------- | ------------- | ------------- | -------------
687-
**enumHeaderStringArray** | [**[]string**](string.md) | Header parameter enum test (string array) |
688+
**enumHeaderStringArray** | **[]string** | Header parameter enum test (string array) |
688689
**enumHeaderString** | **string** | Header parameter enum test (string) | [default to &quot;-efg&quot;]
689-
**enumQueryStringArray** | [**[]string**](string.md) | Query parameter enum test (string array) |
690+
**enumQueryStringArray** | **[]string** | Query parameter enum test (string array) |
690691
**enumQueryString** | **string** | Query parameter enum test (string) | [default to &quot;-efg&quot;]
691692
**enumQueryInteger** | **int32** | Query parameter enum test (double) |
692693
**enumQueryDouble** | **float64** | Query parameter enum test (double) |
693-
**enumFormStringArray** | [**[]string**](string.md) | Form parameter enum test (string array) | [default to &quot;$&quot;]
694+
**enumFormStringArray** | **[]string** | Form parameter enum test (string array) | [default to &quot;$&quot;]
694695
**enumFormString** | **string** | Form parameter enum test (string) | [default to &quot;-efg&quot;]
695696

696697
### Return type
@@ -732,12 +733,12 @@ import (
732733
)
733734

734735
func main() {
735-
requiredStringGroup := 987 // int32 | Required String in group parameters
736+
requiredStringGroup := int32(56) // int32 | Required String in group parameters
736737
requiredBooleanGroup := true // bool | Required Boolean in group parameters
737-
requiredInt64Group := 987 // int64 | Required Integer in group parameters
738-
stringGroup := 987 // int32 | String in group parameters (optional)
738+
requiredInt64Group := int64(789) // int64 | Required Integer in group parameters
739+
stringGroup := int32(56) // int32 | String in group parameters (optional)
739740
booleanGroup := true // bool | Boolean in group parameters (optional)
740-
int64Group := 987 // int64 | Integer in group parameters (optional)
741+
int64Group := int64(789) // int64 | Integer in group parameters (optional)
741742

742743
configuration := openapiclient.NewConfiguration()
743744
api_client := openapiclient.NewAPIClient(configuration)
@@ -804,7 +805,7 @@ import (
804805
)
805806

806807
func main() {
807-
param := map[string]string{ "key": "Inner_example"} // map[string]string | request body
808+
param := map[string]string{"key": "Inner_example"} // map[string]string | request body
808809

809810
configuration := openapiclient.NewConfiguration()
810811
api_client := openapiclient.NewAPIClient(configuration)
@@ -827,7 +828,7 @@ Other parameters are passed through a pointer to a apiTestInlineAdditionalProper
827828

828829
Name | Type | Description | Notes
829830
------------- | ------------- | ------------- | -------------
830-
**param** | [**map[string]string**](string.md) | request body |
831+
**param** | **map[string]string** | request body |
831832

832833
### Return type
833834

@@ -959,11 +960,11 @@ Other parameters are passed through a pointer to a apiTestQueryParameterCollecti
959960

960961
Name | Type | Description | Notes
961962
------------- | ------------- | ------------- | -------------
962-
**pipe** | [**[]string**](string.md) | |
963-
**ioutil** | [**[]string**](string.md) | |
964-
**http** | [**[]string**](string.md) | |
965-
**url** | [**[]string**](string.md) | |
966-
**context** | [**[]string**](string.md) | |
963+
**pipe** | **[]string** | |
964+
**ioutil** | **[]string** | |
965+
**http** | **[]string** | |
966+
**url** | **[]string** | |
967+
**context** | **[]string** | |
967968

968969
### Return type
969970

samples/client/petstore/go/go-petstore/docs/OuterEnum.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# OuterEnum
22

3-
## Properties
3+
## Enum
44

5-
Name | Type | Description | Notes
6-
------------ | ------------- | ------------- | -------------
5+
6+
* `PLACED` (value: `"placed"`)
7+
8+
* `APPROVED` (value: `"approved"`)
9+
10+
* `DELIVERED` (value: `"delivered"`)
711

812

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

0 commit comments

Comments
 (0)