Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[go-experimental] export required fields without pointer #3989

Merged
merged 6 commits into from
Oct 14, 2019
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 @@ -36,14 +36,12 @@ public GoClientExperimentalCodegen() {
outputFolder = "generated-code/go-experimental";
embeddedTemplateDir = templateDir = "go-experimental";

generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.EXPERIMENTAL)
.build();
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata).stability(Stability.EXPERIMENTAL).build();
}

/**
* Configures a friendly name for the generator. This will be used by the generator
* to select the library with the -g flag.
* Configures a friendly name for the generator. This will be used by the
* generator to select the library with the -g flag.
*
* @return the friendly name for the generator
*/
Expand All @@ -53,7 +51,7 @@ public String getName() {
}

/**
* Returns human-friendly help for the generator. Provide the consumer with help
* Returns human-friendly help for the generator. Provide the consumer with help
* tips, parameters here
*
* @return A string value for the help message
Expand All @@ -70,24 +68,25 @@ public void processOpts() {
}

@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
objs = super.postProcessModels(objs);
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");

boolean addedErrorsImport = false;
List<Map<String, Object>> models = (List<Map<String, Object>>) objs.get("models");
for (Map<String, Object> m : models) {
Object v = m.get("model");
if (v instanceof CodegenModel) {
CodegenModel model = (CodegenModel) v;
if (!model.isEnum) {
imports.add(createMapping("import", "encoding/json"));
if (model.isEnum) {
continue;
}

for (CodegenProperty param : model.vars) {
if (!addedErrorsImport && param.required) {
imports.add(createMapping("import", "errors"));
addedErrorsImport = true;
if (!param.isNullable) {
continue;
}

param.dataType = "Nullable" + Character.toUpperCase(param.dataType.charAt(0))
+ param.dataType.substring(1);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{{>partial_header}}
package {{packageName}}

{{#models}}
{{#imports}}
{{#-first}}
import (
{{/-first}}
"bytes"
"encoding/json"
{{#imports}}
"{{import}}"
{{#-last}}
)
{{/-last}}
{{/imports}}
)

{{#model}}
{{#isEnum}}
// {{{classname}}} {{#description}}{{{.}}}{{/description}}{{^description}}the model '{{{classname}}}'{{/description}}
Expand All @@ -25,6 +25,32 @@ const (
{{/enumVars}}
{{/allowableValues}}
)

type Nullable{{{classname}}} struct {
Value {{{classname}}}
ExplicitNull bool
}

func (v Nullable{{{classname}}}) MarshalJSON() ([]byte, error) {
switch {
case v.ExplicitNull && v.Value != "":
return nil, ErrInvalidNullable
case v.ExplicitNull:
return []byte("null"), nil
default:
return json.Marshal(v.Value)
}
}

func (v *Nullable{{{classname}}}) UnmarshalJSON(src []byte) error {
if bytes.Equal(src, []byte("null")) {
v.ExplicitNull = true
return nil
}

return json.Unmarshal(src, &v.Value)
}

{{/isEnum}}
{{^isEnum}}
// {{classname}}{{#description}} {{{description}}}{{/description}}{{^description}} struct for {{{classname}}}{{/description}}
Expand All @@ -35,15 +61,32 @@ type {{classname}} struct {
{{#description}}
// {{{description}}}
{{/description}}
{{name}} *{{{dataType}}} `json:"{{baseName}},omitempty"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{#isNullable}} isExplicitNull{{name}} bool `json:"-"{{#withXml}} xml:"-"{{/withXml}}`{{/isNullable}}
{{name}} {{^required}}*{{/required}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
{{/vars}}
}
{{/isEnum}}

{{^isEnum}}
{{#vars}}
// Get{{name}} returns the {{name}} field if non-nil, zero value otherwise.
{{#required}}
// Get{{name}} returns the {{name}} field value
func (o *{{classname}}) Get{{name}}() {{dataType}} {
if o == nil {
var ret {{dataType}}
return ret
}

return o.{{name}}
}

// Set{{name}} sets field value
func (o *{{classname}}) Set{{name}}(v {{dataType}}) {
o.{{name}} = v
}

{{/required}}
{{^required}}
// Get{{name}} returns the {{name}} field value if set, zero value otherwise.
func (o *{{classname}}) Get{{name}}() {{dataType}} {
if o == nil || o.{{name}} == nil {
var ret {{dataType}}
Expand All @@ -52,7 +95,7 @@ func (o *{{classname}}) Get{{name}}() {{dataType}} {
return *o.{{name}}
}

// Get{{name}}Ok returns a tuple with the {{name}} field if it's non-nil, zero value otherwise
// Get{{name}}Ok returns a tuple with the {{name}} field value if set, zero value otherwise
// and a boolean to check if the value has been set.
func (o *{{classname}}) Get{{name}}Ok() ({{dataType}}, bool) {
if o == nil || o.{{name}} == nil {
Expand All @@ -76,54 +119,30 @@ func (o *{{classname}}) Set{{name}}(v {{dataType}}) {
o.{{name}} = &v
}

{{#isNullable}}
// Set{{name}}ExplicitNull (un)sets {{name}} to be considered as explicit "null" value
// when serializing to JSON (pass true as argument to set this, false to unset)
// The {{name}} value is set to nil even if false is passed
func (o *{{classname}}) Set{{name}}ExplicitNull(b bool) {
o.{{name}} = nil
o.isExplicitNull{{name}} = b
}
{{/isNullable}}
{{/required}}
{{/vars}}
type Nullable{{{classname}}} struct {
Value {{{classname}}}
ExplicitNull bool
}

// MarshalJSON returns the JSON representation of the model.
func (o {{classname}}) MarshalJSON() ([]byte, error) {
toSerialize := map[string]interface{}{}
{{#vars}}
{{#required}}
{{! if argument is required and not nullable, it can't be nil}}
{{^isNullable}}
if o.{{name}} == nil {
return nil, errors.New("{{name}} is required and not nullable, but was not set on {{classname}}")
}{{/isNullable}}
{{! if argument is required and nullable, it *must* have isExplicitNull<name> set to true when it's nil}}
{{#isNullable}}
if o.{{name}} == nil && !o.isExplicitNull{{name}} {
return nil, errors.New("{{name}} is required and nullable, but it wasn't set to be explicit null")
}
{{/isNullable}}
{{/required}}
{{! if argument is nullable, only serialize it if it is nil *and* was explicitly set to nil}}
{{#isNullable}}
if o.{{name}} == nil {
if o.isExplicitNull{{name}} {
toSerialize["{{baseName}}"] = o.{{name}}
}
} else {
toSerialize["{{baseName}}"] = o.{{name}}
}
{{/isNullable}}
{{! if argument is not nullable, don't set it if it is nil}}
{{^isNullable}}
if o.{{name}} != nil {
toSerialize["{{baseName}}"] = o.{{name}}
}
{{/isNullable}}
{{/vars}}
return json.Marshal(toSerialize)
func (v Nullable{{{classname}}}) MarshalJSON() ([]byte, error) {
switch {
case v.ExplicitNull:
return []byte("null"), nil
default:
return json.Marshal(v.Value)
}
}

func (v *Nullable{{{classname}}}) UnmarshalJSON(src []byte) error {
if bytes.Equal(src, []byte("null")) {
v.ExplicitNull = true
return nil
}

return json.Unmarshal(src, &v.Value)
}
{{/isEnum}}

{{/model}}
Expand Down
Loading