Skip to content

Commit d1e75b0

Browse files
antihaxwing328
authored andcommitted
Golang Client Refactor (body and model in errors, typed optional parameters) (#7987)
* Return abstracted errors with model data if available. * update tests with error models. * Return error models on the abstract type. * dont leak FH * duplicate of PR #7752 for issue #7511 * Change optional parameters to structs. * update documentation * fix circleCI failure
1 parent ffb3bda commit d1e75b0

File tree

88 files changed

+2933
-1203
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2933
-1203
lines changed

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractGoCodegen.java

Lines changed: 82 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,11 @@ public AbstractGoCodegen() {
8080
typeMapping.put("UUID", "string");
8181

8282
importMapping = new HashMap<String, String>();
83-
importMapping.put("time.Time", "time");
84-
importMapping.put("*os.File", "os");
8583

8684
cliOptions.clear();
8785
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Go package name (convention: lowercase).")
8886
.defaultValue("swagger"));
87+
8988
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, CodegenConstants.HIDE_GENERATION_TIMESTAMP_DESC)
9089
.defaultValue(Boolean.TRUE.toString()));
9190
}
@@ -97,8 +96,7 @@ public AbstractGoCodegen() {
9796
* @return the escaped term
9897
*/
9998
@Override
100-
public String escapeReservedWord(String name)
101-
{
99+
public String escapeReservedWord(String name) {
102100
// Can't start with an underscore, as our fields need to start with an
103101
// UppercaseLetter so that Go treats them as public/visible.
104102

@@ -110,7 +108,7 @@ public String escapeReservedWord(String name)
110108
// - X_Name
111109
// ... or maybe a suffix?
112110
// - Name_ ... think this will work.
113-
if(this.reservedWordsMappings().containsKey(name)) {
111+
if (this.reservedWordsMappings().containsKey(name)) {
114112
return this.reservedWordsMappings().get(name);
115113
}
116114
return camelize(name) + '_';
@@ -160,7 +158,7 @@ public String toModelName(String name) {
160158

161159
@Override
162160
public String toModelFilename(String name) {
163-
return toModel("model_" + name);
161+
return toModel("model_" + name);
164162
}
165163

166164
public String toModel(String name) {
@@ -182,7 +180,8 @@ public String toModel(String name) {
182180

183181
// model name starts with number
184182
if (name.matches("^\\d.*")) {
185-
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + ("model_" + name));
183+
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to "
184+
+ ("model_" + name));
186185
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
187186
}
188187

@@ -206,33 +205,30 @@ public String toApiFilename(String name) {
206205
* @param parameter CodegenParameter object to be processed.
207206
*/
208207
@Override
209-
public void postProcessParameter(CodegenParameter parameter){
208+
public void postProcessParameter(CodegenParameter parameter) {
210209

211210
// Give the base class a chance to process
212211
super.postProcessParameter(parameter);
213212

214-
char firstChar = parameter.paramName.charAt(0);
215-
216-
if (Character.isUpperCase(firstChar)) {
213+
char nameFirstChar = parameter.paramName.charAt(0);
214+
if (Character.isUpperCase(nameFirstChar)) {
217215
// First char is already uppercase, just use paramName.
218216
parameter.vendorExtensions.put("x-exportParamName", parameter.paramName);
219-
217+
} else {
218+
// It's a lowercase first char, let's convert it to uppercase
219+
StringBuilder sb = new StringBuilder(parameter.paramName);
220+
sb.setCharAt(0, Character.toUpperCase(nameFirstChar));
221+
parameter.vendorExtensions.put("x-exportParamName", sb.toString());
220222
}
221-
222-
// It's a lowercase first char, let's convert it to uppercase
223-
StringBuilder sb = new StringBuilder(parameter.paramName);
224-
sb.setCharAt(0, Character.toUpperCase(firstChar));
225-
parameter.vendorExtensions.put("x-exportParamName", sb.toString());
226223
}
227224

228225
@Override
229226
public String getTypeDeclaration(Property p) {
230-
if(p instanceof ArrayProperty) {
227+
if (p instanceof ArrayProperty) {
231228
ArrayProperty ap = (ArrayProperty) p;
232229
Property inner = ap.getItems();
233230
return "[]" + getTypeDeclaration(inner);
234-
}
235-
else if (p instanceof MapProperty) {
231+
} else if (p instanceof MapProperty) {
236232
MapProperty mp = (MapProperty) p;
237233
Property inner = mp.getAdditionalProperties();
238234

@@ -247,11 +243,11 @@ else if (p instanceof MapProperty) {
247243
return typeMapping.get(swaggerType);
248244
}
249245

250-
if(typeMapping.containsValue(swaggerType)) {
246+
if (typeMapping.containsValue(swaggerType)) {
251247
return swaggerType;
252248
}
253249

254-
if(languageSpecificPrimitives.contains(swaggerType)) {
250+
if (languageSpecificPrimitives.contains(swaggerType)) {
255251
return swaggerType;
256252
}
257253

@@ -262,12 +258,11 @@ else if (p instanceof MapProperty) {
262258
public String getSwaggerType(Property p) {
263259
String swaggerType = super.getSwaggerType(p);
264260
String type = null;
265-
if(typeMapping.containsKey(swaggerType)) {
261+
if (typeMapping.containsKey(swaggerType)) {
266262
type = typeMapping.get(swaggerType);
267-
if(languageSpecificPrimitives.contains(type))
263+
if (languageSpecificPrimitives.contains(type))
268264
return (type);
269-
}
270-
else
265+
} else
271266
type = swaggerType;
272267
return type;
273268
}
@@ -278,7 +273,8 @@ public String toOperationId(String operationId) {
278273

279274
// method name cannot use reserved keyword, e.g. return
280275
if (isReservedWord(sanitizedOperationId)) {
281-
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + camelize("call_" + operationId));
276+
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to "
277+
+ camelize("call_" + operationId));
282278
sanitizedOperationId = "call_" + sanitizedOperationId;
283279
}
284280

@@ -308,21 +304,48 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
308304
iterator.remove();
309305
}
310306

311-
// if their is a return type, import encoding/json and if needed encoding/xml
307+
// this will only import "fmt" if there are items in pathParams
312308
for (CodegenOperation operation : operations) {
313-
if(operation.returnBaseType != null ) {
314-
imports.add(createMapping("import", "encoding/json"));
315-
if (withXml)
316-
imports.add(createMapping("import", "encoding/xml"));
309+
if (operation.pathParams != null && operation.pathParams.size() > 0) {
310+
imports.add(createMapping("import", "fmt"));
317311
break; //just need to import once
318312
}
319313
}
320314

321-
// this will only import "fmt" if there are items in pathParams
315+
boolean addedOptionalImport = false;
316+
boolean addedTimeImport = false;
317+
boolean addedOSImport = false;
322318
for (CodegenOperation operation : operations) {
323-
if(operation.pathParams != null && operation.pathParams.size() > 0) {
324-
imports.add(createMapping("import", "fmt"));
325-
break; //just need to import once
319+
for (CodegenParameter param : operation.allParams) {
320+
// import "os" if the operation uses files
321+
if (!addedOSImport && param.dataType == "*os.File") {
322+
imports.add(createMapping("import", "os"));
323+
addedOSImport = true;
324+
}
325+
326+
// import "time" if the operation has a required time parameter.
327+
if (param.required) {
328+
if (!addedTimeImport && param.dataType == "time.Time") {
329+
imports.add(createMapping("import", "time"));
330+
addedTimeImport = true;
331+
}
332+
}
333+
334+
// import "optionals" package if the parameter is primitive and optional
335+
if (!param.required && param.isPrimitiveType) {
336+
if (!addedOptionalImport) {
337+
imports.add(createMapping("import", "github.com/antihax/optional"));
338+
addedOptionalImport = true;
339+
}
340+
// We need to specially map Time type to the optionals package
341+
if (param.dataType == "time.Time") {
342+
param.vendorExtensions.put("x-optionalDataType", "Time");
343+
continue;
344+
}
345+
// Map optional type to dataType
346+
param.vendorExtensions.put("x-optionalDataType",
347+
param.dataType.substring(0, 1).toUpperCase() + param.dataType.substring(1));
348+
}
326349
}
327350
}
328351

@@ -356,6 +379,25 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
356379
iterator.remove();
357380
}
358381

382+
boolean addedTimeImport = false;
383+
boolean addedOSImport = false;
384+
List<Map<String, Object>> models = (List<Map<String, Object>>) objs.get("models");
385+
for (Map<String, Object> m : models) {
386+
Object v = m.get("model");
387+
if (v instanceof CodegenModel) {
388+
CodegenModel model = (CodegenModel) v;
389+
for (CodegenProperty param : model.vars) {
390+
if (!addedTimeImport && param.baseType == "time.Time") {
391+
imports.add(createMapping("import", "time"));
392+
addedTimeImport = true;
393+
}
394+
if (!addedOSImport && param.baseType == "*os.File") {
395+
imports.add(createMapping("import", "os"));
396+
addedOSImport = true;
397+
}
398+
}
399+
}
400+
}
359401
// recursively add import for mapping one type to multiple imports
360402
List<Map<String, String>> recursiveImports = (List<Map<String, String>>) objs.get("imports");
361403
if (recursiveImports == null)
@@ -376,8 +418,8 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
376418

377419
@Override
378420
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
379-
Swagger swagger = (Swagger)objs.get("swagger");
380-
if(swagger != null) {
421+
Swagger swagger = (Swagger) objs.get("swagger");
422+
if (swagger != null) {
381423
try {
382424
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(swagger));
383425
} catch (JsonProcessingException e) {
@@ -389,8 +431,7 @@ public Map<String, Object> postProcessSupportingFileData(Map<String, Object> obj
389431

390432
@Override
391433
protected boolean needToImport(String type) {
392-
return !defaultIncludes.contains(type)
393-
&& !languageSpecificPrimitives.contains(type);
434+
return !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type);
394435
}
395436

396437
public void setPackageName(String packageName) {
@@ -408,7 +449,7 @@ public String escapeUnsafeCharacters(String input) {
408449
return input.replace("*/", "*_/").replace("/*", "/_*");
409450
}
410451

411-
public Map<String, String> createMapping(String key, String value){
452+
public Map<String, String> createMapping(String key, String value) {
412453
Map<String, String> customImport = new HashMap<String, String>();
413454
customImport.put(key, value);
414455

0 commit comments

Comments
 (0)