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] Set Default Values for Required Variables when a default is defined #19232

Merged
merged 8 commits into from
Jul 30, 2024
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
1 change: 1 addition & 0 deletions bin/configs/go-petstore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ additionalProperties:
packageName: petstore
disallowAdditionalPropertiesIfNotPresent: false
generateInterfaces: true
useDefaultValuesForRequiredVars: "true"
enumNameMappings:
delivered: SHIPPED

1 change: 1 addition & 0 deletions docs/generators/go.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|packageVersion|Go package version.| |1.0.0|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|structPrefix|whether to prefix struct with the class name. e.g. DeletePetOpts => PetApiDeletePetOpts| |false|
|useDefaultValuesForRequiredVars|Use default values for required variables when available| |false|
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped.| |false|
|withAWSV4Signature|whether to include AWS v4 signature support| |false|
|withGoMod|Generate go.mod and go.sum| |true|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,4 +451,6 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case,
public static final String MAX_ATTEMPTS_FOR_RETRY = "maxAttemptsForRetry";

public static final String WAIT_TIME_OF_THREAD = "waitTimeMillis";

public static final String USE_DEFAULT_VALUES_FOR_REQUIRED_VARS = "useDefaultValuesForRequiredVars";
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public abstract class AbstractGoCodegen extends DefaultCodegen implements Codege
protected boolean generateMarshalJSON = true;
@Setter
protected boolean generateUnmarshalJSON = true;
@Setter
protected boolean useDefaultValuesForRequiredVars = false;

@Setter
protected String packageName = "openapi";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class GoClientCodegen extends AbstractGoCodegen {
public static final String GENERATE_INTERFACES = "generateInterfaces";
public static final String MODEL_FILE_FOLDER = "modelFileFolder";
public static final String WITH_GO_MOD = "withGoMod";
public static final String USE_DEFAULT_VALUES_FOR_REQUIRED_VARS = "useDefaultValuesForRequiredVars";
@Setter protected String goImportAlias = "openapiclient";
protected boolean isGoSubmodule = false;
@Setter protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup
Expand Down Expand Up @@ -126,6 +127,7 @@ public GoClientCodegen() {
cliOptions.add(CliOption.newBoolean(STRUCT_PREFIX, "whether to prefix struct with the class name. e.g. DeletePetOpts => PetApiDeletePetOpts"));
cliOptions.add(CliOption.newBoolean(WITH_AWSV4_SIGNATURE, "whether to include AWS v4 signature support"));
cliOptions.add(CliOption.newBoolean(GENERATE_INTERFACES, "Generate interfaces for api classes"));
cliOptions.add(CliOption.newBoolean(USE_DEFAULT_VALUES_FOR_REQUIRED_VARS, "Use default values for required variables when available"));

// option to change the order of form/body parameter
cliOptions.add(CliOption.newBoolean(
Expand Down Expand Up @@ -246,6 +248,11 @@ public void processOpts() {
additionalProperties.put(GENERATE_INTERFACES, generateInterfaces);
}

if (additionalProperties.containsKey(USE_DEFAULT_VALUES_FOR_REQUIRED_VARS)) {
setUseDefaultValuesForRequiredVars(Boolean.parseBoolean(additionalProperties.get(USE_DEFAULT_VALUES_FOR_REQUIRED_VARS).toString()));
additionalProperties.put(USE_DEFAULT_VALUES_FOR_REQUIRED_VARS, useDefaultValuesForRequiredVars);
}

// Generate the 'signing.py' module, but only if the 'HTTP signature' security scheme is specified in the OAS.
Map<String, SecurityScheme> securitySchemeMap = openAPI != null ?
(openAPI.getComponents() != null ? openAPI.getComponents().getSecuritySchemes() : null) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}}) {
{{/isNullable}}
}

{{#useDefaultValuesForRequiredVars}}
{{^isReadOnly}}
{{#defaultValue}}
// GetDefault{{baseName}} function assigns the default value {{defaultValue}} to the {{name}} field
// of the {{classname}} struct and returns the {{{defaultValue}}}.
func (o *{{classname}}) GetDefault{{nameInPascalCase}}() interface{} {
return {{{defaultValue}}}
}
{{/defaultValue}}
{{/isReadOnly}}
{{/useDefaultValuesForRequiredVars}}
vvb marked this conversation as resolved.
Show resolved Hide resolved

{{/required}}
{{^required}}
// Get{{name}} returns the {{name}} field value if set, zero value otherwise{{#isNullable}} (both if not set or set to explicit null){{/isNullable}}.
Expand Down Expand Up @@ -318,6 +330,15 @@ func (o {{classname}}) ToMap() (map[string]interface{}, error) {
{{! if argument is not nullable, don't set it if it is nil}}
{{^isNullable}}
{{#required}}
{{#useDefaultValuesForRequiredVars}}
{{^isReadOnly}}
{{#defaultValue}}
if _, exists := toSerialize["{{{baseName}}}"]; !exists {
toSerialize["{{{baseName}}}"] = o.GetDefault{{nameInPascalCase}}()
}
{{/defaultValue}}
{{/isReadOnly}}
{{/useDefaultValuesForRequiredVars}}
toSerialize["{{{baseName}}}"] = o.{{name}}
{{/required}}
{{^required}}
Expand Down Expand Up @@ -356,6 +377,20 @@ func (o *{{{classname}}}) UnmarshalJSON(data []byte) (err error) {
{{/requiredVars}}
}

{{#useDefaultValuesForRequiredVars}}
// defaultValueFuncMap captures the default values for required properties.
// These values are used when required properties are missing from the payload.
defaultValueFuncMap := map[string]func() interface{} {
{{#requiredVars}}
{{#defaultValue}}
{{^isReadOnly}}
"{{baseName}}": o.GetDefault{{nameInPascalCase}},
{{/isReadOnly}}
{{/defaultValue}}
{{/requiredVars}}
}
var defaultValueApplied bool
{{/useDefaultValuesForRequiredVars}}
allProperties := make(map[string]interface{})

err = json.Unmarshal(data, &allProperties)
Expand All @@ -365,11 +400,30 @@ func (o *{{{classname}}}) UnmarshalJSON(data []byte) (err error) {
}

for _, requiredProperty := range(requiredProperties) {
{{#useDefaultValuesForRequiredVars}}
if value, exists := allProperties[requiredProperty]; !exists || value == "" {
if _, ok := defaultValueFuncMap[requiredProperty]; ok {
allProperties[requiredProperty] = defaultValueFuncMap[requiredProperty]()
defaultValueApplied = true
}
}
if value, exists := allProperties[requiredProperty]; !exists || value == ""{
{{/useDefaultValuesForRequiredVars}}
{{^useDefaultValuesForRequiredVars}}
if _, exists := allProperties[requiredProperty]; !exists {
{{/useDefaultValuesForRequiredVars}}
return fmt.Errorf("no value given for required property %v", requiredProperty)
}
}

{{#useDefaultValuesForRequiredVars}}
if defaultValueApplied {
data, err = json.Marshal(allProperties)
if err != nil{
return err
}
}
{{/useDefaultValuesForRequiredVars}}
{{/hasRequired}}
{{#isAdditionalPropertiesTrue}}
{{#parent}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ protected void verifyOptions() {
verify(clientCodegen).setWithGoMod(GoClientOptionsProvider.WITH_GO_MOD_VALUE);
verify(clientCodegen).setGenerateMarshalJSON(GoClientOptionsProvider.GENERATE_MARSHAL_JSON_VALUE);
verify(clientCodegen).setGenerateUnmarshalJSON(GoClientOptionsProvider.GENERATE_UNMARSHAL_JSON_VALUE);
verify(clientCodegen).setUseDefaultValuesForRequiredVars(GoClientOptionsProvider.USE_DEFAULT_VALUES_FOR_REQUIRED_VARS_VALUE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class GoClientOptionsProvider implements OptionsProvider {
public static final boolean WITH_GO_MOD_VALUE = true;
public static final boolean GENERATE_MARSHAL_JSON_VALUE = true;
public static final boolean GENERATE_UNMARSHAL_JSON_VALUE = true;
public static final boolean USE_DEFAULT_VALUES_FOR_REQUIRED_VARS_VALUE = true;

@Override
public String getLanguage() {
Expand All @@ -64,6 +65,7 @@ public Map<String, String> createOptions() {
.put(CodegenConstants.GENERATE_UNMARSHAL_JSON, "true")
.put("generateInterfaces", "true")
.put("structPrefix", "true")
.put(CodegenConstants.USE_DEFAULT_VALUES_FOR_REQUIRED_VARS, "true")
.build();
}

Expand Down
2 changes: 2 additions & 0 deletions samples/client/echo_api/go-external-refs/model_pet.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions samples/client/echo_api/go/model_pet.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions samples/client/petstore/go/go-petstore/model_animal.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions samples/client/petstore/go/go-petstore/model_category.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions samples/client/petstore/go/go-petstore/model_enum_test_.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions samples/client/petstore/go/go-petstore/model_format_test_.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions samples/client/petstore/go/go-petstore/model_name.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions samples/client/petstore/go/go-petstore/model_pet.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading