Skip to content
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

Go client codegen #641

Merged
merged 9 commits into from
Apr 5, 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
Original file line number Diff line number Diff line change
Expand Up @@ -2173,9 +2173,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
} else if (param instanceof CookieParameter || "cookie".equalsIgnoreCase(param.getIn())) {
cookieParams.add(codegenParameter.copy());
}
if (!codegenParameter.required) {
codegenOperation.getVendorExtensions().put(CodegenConstants.HAS_OPTIONAL_PARAMS_EXT_NAME, Boolean.TRUE);
} else {
if (codegenParameter.required) {
requiredParams.add(codegenParameter.copy());
}
}
Expand Down Expand Up @@ -2222,6 +2220,10 @@ public int compare(CodegenParameter one, CodegenParameter another) {
boolean hasRequiredParams = codegenOperation.requiredParams.size() > 0;
codegenOperation.getVendorExtensions().put(CodegenConstants.HAS_REQUIRED_PARAMS_EXT_NAME, hasRequiredParams);

boolean hasOptionalParams = codegenOperation.allParams.stream()
.anyMatch(codegenParameter -> !codegenParameter.required);
codegenOperation.getVendorExtensions().put(CodegenConstants.HAS_OPTIONAL_PARAMS_EXT_NAME, hasOptionalParams);

// set Restful Flag
codegenOperation.getVendorExtensions().put(CodegenConstants.IS_RESTFUL_SHOW_EXT_NAME, codegenOperation.getIsRestfulShow());
codegenOperation.getVendorExtensions().put(CodegenConstants.IS_RESTFUL_INDEX_EXT_NAME, codegenOperation.getIsRestfulIndex());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package io.swagger.codegen.v3.generators.go;

import io.swagger.codegen.v3.CliOption;
import io.swagger.codegen.v3.CodegenConfig;
import io.swagger.codegen.v3.CodegenConstants;
import io.swagger.codegen.v3.CodegenContent;
import io.swagger.codegen.v3.CodegenModel;
import io.swagger.codegen.v3.CodegenOperation;
import io.swagger.codegen.v3.CodegenParameter;
import io.swagger.codegen.v3.CodegenProperty;
import io.swagger.codegen.v3.ISchemaHandler;
import io.swagger.codegen.v3.generators.DefaultCodegenConfig;
import io.swagger.codegen.v3.generators.util.OpenAPIUtil;
import io.swagger.v3.core.util.Yaml;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.ArraySchema;
Expand Down Expand Up @@ -77,6 +79,7 @@ public AbstractGoCodegen() {
typeMapping.put("number", "float32");
typeMapping.put("float", "float32");
typeMapping.put("double", "float64");
typeMapping.put("BigDecimal", "float64");
typeMapping.put("boolean", "bool");
typeMapping.put("string", "string");
typeMapping.put("UUID", "string");
Expand Down Expand Up @@ -265,6 +268,14 @@ public String getTypeDeclaration(Schema schema) {
@Override
public String getSchemaType(Schema schema) {
String schemaType = super.getSchemaType(schema);

if (schema.get$ref() != null) {
final Schema refSchema = OpenAPIUtil.getSchemaFromName(schemaType, this.openAPI);
if (refSchema != null && !isObjectSchema(refSchema)) {
schemaType = super.getSchemaType(refSchema);
}
}

String type;
if(typeMapping.containsKey(schemaType)) {
type = typeMapping.get(schemaType);
Expand Down Expand Up @@ -325,34 +336,36 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
boolean addedTimeImport = false;
boolean addedOSImport = false;
for (CodegenOperation operation : operations) {
for (CodegenParameter param : operation.allParams) {
// import "os" if the operation uses files
if (!addedOSImport && param.dataType == "*os.File") {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}

// import "time" if the operation has a required time parameter.
if (param.required) {
if (!addedTimeImport && param.dataType == "time.Time") {
imports.add(createMapping("import", "time"));
addedTimeImport = true;
for (CodegenContent codegenContent : operation.getContents()) {
for (CodegenParameter param : codegenContent.getParameters()) {
// import "os" if the operation uses files
if (!addedOSImport && param.dataType == "*os.File") {
imports.add(createMapping("import", "os"));
addedOSImport = true;
}
}

// import "optionals" package if the parameter is primitive and optional
if (!param.required && getBooleanValue(param, CodegenConstants.IS_PRIMITIVE_TYPE_EXT_NAME)) {
if (!addedOptionalImport) {
imports.add(createMapping("import", "github.com/antihax/optional"));
addedOptionalImport = true;
// import "time" if the operation has a required time parameter.
if (param.required) {
if (!addedTimeImport && param.dataType == "time.Time") {
imports.add(createMapping("import", "time"));
addedTimeImport = true;
}
}
// We need to specially map Time type to the optionals package
if (param.dataType == "time.Time") {
param.vendorExtensions.put("x-optionalDataType", "Time");
continue;

// import "optionals" package if the parameter is primitive and optional
if (!param.required && param.getIsPrimitiveType()) {
if (!addedOptionalImport) {
imports.add(createMapping("import", "github.com/antihax/optional"));
addedOptionalImport = true;
}
// We need to specially map Time type to the optionals package
if (param.dataType == "time.Time") {
param.vendorExtensions.put("x-optionalDataType", "Time");
continue;
}
// Map optional type to dataType
param.vendorExtensions.put("x-optionalDataType", param.dataType.substring(0, 1).toUpperCase() + param.dataType.substring(1));
}
// Map optional type to dataType
param.vendorExtensions.put("x-optionalDataType", param.dataType.substring(0, 1).toUpperCase() + param.dataType.substring(1));
}
}
}
Expand Down Expand Up @@ -426,7 +439,7 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {

@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
OpenAPI openAPI = (OpenAPI)objs.get("openapi");
OpenAPI openAPI = (OpenAPI)objs.get("openAPI");
if(openAPI != null) {
try {
objs.put("swagger-yaml", Yaml.mapper().writeValueAsString(openAPI));
Expand Down Expand Up @@ -527,4 +540,25 @@ public String toEnumName(CodegenProperty property) {
public void setWithXml(boolean withXml) {
this.withXml = withXml;
}

@Override
public CodegenModel fromModel(String name, Schema schema, Map<String, Schema> allDefinitions) {
final CodegenModel codegenModel = super.fromModel(name, schema, allDefinitions);
if (!getBooleanValue(codegenModel, CodegenConstants.IS_ALIAS_EXT_NAME)) {
boolean isAlias = schema instanceof ArraySchema
|| schema instanceof MapSchema
|| (!isObjectSchema(schema));

codegenModel.getVendorExtensions().put(CodegenConstants.IS_ALIAS_EXT_NAME, isAlias);
}



return codegenModel;
}

@Override
public ISchemaHandler getSchemaHandler() {
return new GoSchemaHandler(this);
}
}
129 changes: 129 additions & 0 deletions src/main/java/io/swagger/codegen/v3/generators/go/GoClientCodegen.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package io.swagger.codegen.v3.generators.go;

import io.swagger.codegen.v3.CliOption;
import io.swagger.codegen.v3.CodegenOperation;
import io.swagger.codegen.v3.CodegenType;
import io.swagger.codegen.v3.SupportingFile;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.Arrays;
import java.util.Map;

public class GoClientCodegen extends AbstractGoCodegen {
protected String packageVersion = "1.0.0";
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";
public static final String WITH_XML = "withXml";

public GoClientCodegen() {
this.outputFolder = "generated-code/go";
this.modelTemplateFiles.put("model.mustache", ".go");
this.apiTemplateFiles.put("api.mustache", ".go");
this.modelDocTemplateFiles.put("model_doc.mustache", ".md");
this.apiDocTemplateFiles.put("api_doc.mustache", ".md");
this.hideGenerationTimestamp = Boolean.TRUE;
this.setReservedWordsLowerCase(Arrays.asList("string", "bool", "uint", "uint8", "uint16", "uint32", "uint64", "int", "int8", "int16", "int32", "int64", "float32", "float64", "complex64", "complex128", "rune", "byte", "uintptr", "break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for", "import", "return", "var", "error", "ApiResponse", "nil"));
this.cliOptions.add((new CliOption("packageVersion", "Go package version.")).defaultValue("1.0.0"));
this.cliOptions.add(CliOption.newBoolean("withXml", "whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)"));
}

@Override
public String getDefaultTemplateDir() {
return "go";
}

public void processOpts() {
super.processOpts();

if (StringUtils.isBlank(templateDir)) {
embeddedTemplateDir = templateDir = getTemplateDir();
}

if (this.additionalProperties.containsKey("packageName")) {
this.setPackageName((String)this.additionalProperties.get("packageName"));
} else {
this.setPackageName("swagger");
}

if (this.additionalProperties.containsKey("packageVersion")) {
this.setPackageVersion((String)this.additionalProperties.get("packageVersion"));
} else {
this.setPackageVersion("1.0.0");
}

this.additionalProperties.put("packageName", this.packageName);
this.additionalProperties.put("packageVersion", this.packageVersion);
this.additionalProperties.put("apiDocPath", this.apiDocPath);
this.additionalProperties.put("modelDocPath", this.modelDocPath);
this.modelPackage = this.packageName;
this.apiPackage = this.packageName;
this.supportingFiles.add(new SupportingFile("swagger.mustache", "api", "swagger.yaml"));
this.supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
this.supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
this.supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
this.supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.go"));
this.supportingFiles.add(new SupportingFile("client.mustache", "", "client.go"));
this.supportingFiles.add(new SupportingFile("response.mustache", "", "response.go"));
this.supportingFiles.add(new SupportingFile(".travis.yml", "", ".travis.yml"));
if (this.additionalProperties.containsKey("withXml")) {
this.setWithXml(Boolean.parseBoolean(this.additionalProperties.get("withXml").toString()));
if (this.withXml) {
this.additionalProperties.put("withXml", "true");
}
}

}

public CodegenType getTag() {
return CodegenType.CLIENT;
}

public String getName() {
return "go";
}

public String getHelp() {
return "Generates a Go client library (beta).";
}

public String apiFileFolder() {
return this.outputFolder + File.separator;
}

public String modelFileFolder() {
return this.outputFolder + File.separator;
}

public String apiDocFileFolder() {
return (this.outputFolder + "/" + this.apiDocPath).replace('/', File.separatorChar);
}

public String modelDocFileFolder() {
return (this.outputFolder + "/" + this.modelDocPath).replace('/', File.separatorChar);
}

public String toModelDocFilename(String name) {
return this.toModelName(name);
}

public String toApiDocFilename(String name) {
return this.toApiName(name);
}

public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}

public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Schema> schemas, OpenAPI openAPI) {
final CodegenOperation codegenOperation = super.fromOperation(path, httpMethod, operation, schemas, openAPI);
if (codegenOperation.getHasBodyParam() || codegenOperation.bodyParam != null) {
codegenOperation.getFormParams().clear();
}
return codegenOperation;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.swagger.codegen.v3.generators.go;

import io.swagger.codegen.v3.CodegenModel;
import io.swagger.codegen.v3.generators.DefaultCodegenConfig;
import io.swagger.codegen.v3.generators.SchemaHandler;
import io.swagger.v3.oas.models.media.Schema;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

public class GoSchemaHandler extends SchemaHandler {

public GoSchemaHandler(DefaultCodegenConfig codegenConfig) {
super(codegenConfig);
}

protected void addInterfaces(List<Schema> schemas, CodegenModel composedModel, Map<String, CodegenModel> allModels) {
for (Schema interfaceSchema : schemas) {
final String ref = interfaceSchema.get$ref();
if (StringUtils.isBlank(ref)) {
continue;
}
final String schemaName = ref.substring(ref.lastIndexOf("/") + 1);
this.addInterfaceModel(composedModel, allModels.get(codegenConfig.toModelName(schemaName)));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
io.swagger.codegen.v3.generators.dotnet.AspNetCoreServerCodegen
io.swagger.codegen.v3.generators.dotnet.CSharpClientCodegen
io.swagger.codegen.v3.generators.dotnet.CsharpDotNet2ClientCodegen
io.swagger.codegen.v3.generators.go.GoClientCodegen
io.swagger.codegen.v3.generators.go.GoServerCodegen
io.swagger.codegen.v3.generators.html.StaticDocCodegen
io.swagger.codegen.v3.generators.html.StaticHtmlCodegen
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/handlebars/go-server/model.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ const (
){{/isEnum}}{{^isEnum}}{{#description}}
// {{{description}}}{{/description}}
type {{classname}} struct {
{{#isComposedModel}}
{{#interfaceModels}}
{{classname}}
{{/interfaceModels}}
{{/isComposedModel}}
{{^isComposedModel}}
{{#vars}}{{#description}}
// {{{description}}}{{/description}}
{{name}} {{^isEnum}}{{^isPrimitiveType}}{{^isContainer}}{{^isDateTime}}*{{/isDateTime}}{{/isContainer}}{{/isPrimitiveType}}{{/isEnum}}{{{datatype}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"`
{{/vars}}
{{/isComposedModel}}
}{{/isEnum}}{{/model}}{{/models}}
8 changes: 8 additions & 0 deletions src/main/resources/handlebars/go/.travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
language: go

install:
- go get -d -v .

script:
- go build -v ./

Loading