Skip to content

Commit 09568ce

Browse files
author
Slavek Kabrda
committed
[Go][client] make structure members pointers, provide custom marshalling.
Fixes #522
1 parent 19f47d0 commit 09568ce

File tree

195 files changed

+21441
-691
lines changed

Some content is hidden

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

195 files changed

+21441
-691
lines changed

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

+31
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@
1919

2020
import org.openapitools.codegen.CliOption;
2121
import org.openapitools.codegen.CodegenConstants;
22+
import org.openapitools.codegen.CodegenModel;
23+
import org.openapitools.codegen.CodegenProperty;
2224
import org.openapitools.codegen.CodegenType;
2325
import org.openapitools.codegen.SupportingFile;
2426
import org.slf4j.Logger;
2527
import org.slf4j.LoggerFactory;
2628

2729
import java.io.File;
30+
import java.util.List;
31+
import java.util.Map;
2832

2933
public class GoClientCodegen extends AbstractGoCodegen {
3034

@@ -99,6 +103,7 @@ public void processOpts() {
99103
supportingFiles.add(new SupportingFile("go.mod.mustache", "", "go.mod"));
100104
supportingFiles.add(new SupportingFile("go.sum", "", "go.sum"));
101105
supportingFiles.add(new SupportingFile(".travis.yml", "", ".travis.yml"));
106+
supportingFiles.add(new SupportingFile("utils.mustache", "", "utils.go"));
102107

103108
if (additionalProperties.containsKey(WITH_GO_CODEGEN_COMMENT)) {
104109
setWithGoCodegenComment(Boolean.parseBoolean(additionalProperties.get(WITH_GO_CODEGEN_COMMENT).toString()));
@@ -122,6 +127,32 @@ public void processOpts() {
122127
}
123128
}
124129

130+
@Override
131+
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
132+
objs = super.postProcessModels(objs);
133+
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
134+
135+
boolean addedErrorsImport = false;
136+
List<Map<String, Object>> models = (List<Map<String, Object>>) objs.get("models");
137+
for (Map<String, Object> m : models) {
138+
Object v = m.get("model");
139+
if (v instanceof CodegenModel) {
140+
CodegenModel model = (CodegenModel) v;
141+
if (!model.isEnum) {
142+
imports.add(createMapping("import", "encoding/json"));
143+
}
144+
for (CodegenProperty param : model.vars) {
145+
if (!addedErrorsImport && param.required) {
146+
imports.add(createMapping("import", "errors"));
147+
addedErrorsImport = true;
148+
}
149+
}
150+
}
151+
}
152+
153+
return objs;
154+
}
155+
125156
/**
126157
* Configures the type of generator.
127158
*

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

+87-1
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,95 @@ type {{classname}} struct {
3535
{{#description}}
3636
// {{{description}}}
3737
{{/description}}
38-
{{name}} {{#isNullable}}*{{/isNullable}}{{{dataType}}} `json:"{{baseName}}{{^required}},omitempty{{/required}}"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
38+
{{name}} *{{{dataType}}} `json:"{{baseName}},omitempty"{{#withXml}} xml:"{{baseName}}{{#isXmlAttribute}},attr{{/isXmlAttribute}}"{{/withXml}}{{#vendorExtensions.x-go-custom-tag}} {{{.}}}{{/vendorExtensions.x-go-custom-tag}}`
39+
{{#isNullable}} isExplicitNull{{name}} bool `json:"-"{{#withXml}} xml:"-"{{/withXml}}`{{/isNullable}}
3940
{{/vars}}
4041
}
4142
{{/isEnum}}
43+
44+
{{^isEnum}}
45+
{{#vars}}
46+
// Get{{name}} returns the {{name}} field if non-nil, zero value otherwise.
47+
func (o *{{classname}}) Get{{name}}() {{dataType}} {
48+
if o == nil || o.{{name}} == nil {
49+
var ret {{dataType}}
50+
return ret
51+
}
52+
return *o.{{name}}
53+
}
54+
55+
// Get{{name}}Ok returns a tuple with the {{name}} field if it's non-nil, zero value otherwise
56+
// and a boolean to check if the value has been set.
57+
func (o *{{classname}}) Get{{name}}Ok() ({{dataType}}, bool) {
58+
if o == nil || o.{{name}} == nil {
59+
var ret {{dataType}}
60+
return ret, false
61+
}
62+
return *o.{{name}}, true
63+
}
64+
65+
// Has{{name}} returns a boolean if a field has been set.
66+
func (o *{{classname}}) Has{{name}}() bool {
67+
if o != nil && o.{{name}} != nil {
68+
return true
69+
}
70+
71+
return false
72+
}
73+
74+
// Set{{name}} gets a reference to the given {{dataType}} and assigns it to the {{name}} field.
75+
func (o *{{classname}}) Set{{name}}(v {{dataType}}) {
76+
o.{{name}} = &v
77+
}
78+
79+
{{#isNullable}}
80+
// Set{{name}}ExplicitNull (un)sets {{name}} to be considered as explicit "null" value
81+
// when serializing to JSON (pass true as argument to set this, false to unset)
82+
// The {{name}} value is set to nil even if false is passed
83+
func (o *{{classname}}) Set{{name}}ExplicitNull(b bool) {
84+
o.{{name}} = nil
85+
o.isExplicitNull{{name}} = b
86+
}
87+
{{/isNullable}}
88+
{{/vars}}
89+
90+
func (o {{classname}}) MarshalJSON() ([]byte, error) {
91+
toSerialize := map[string]interface{}{}
92+
{{#vars}}
93+
{{#required}}
94+
{{! if argument is required and not nullable, it can't be nil}}
95+
{{^isNullable}}
96+
if o.{{name}} == nil {
97+
return nil, errors.New("{{name}} is required and not nullable, but was not set on {{classname}}")
98+
}{{/isNullable}}
99+
{{! if argument is required and nullable, it *must* have isExplicitNull<name> set to true when it's nil}}
100+
{{#isNullable}}
101+
if o.{{name}} == nil && !o.isExplicitNull{{name}} {
102+
return nil, errors.New("{{name}} is required and nullable, but it wasn't set to be explicit null")
103+
}
104+
{{/isNullable}}
105+
{{/required}}
106+
{{! if argument is nullable, only serialize it if it is nil *and* was explicitly set to nil}}
107+
{{#isNullable}}
108+
if o.{{name}} == nil {
109+
if o.isExplicitNull{{name}} {
110+
toSerialize["{{baseName}}"] = o.{{name}}
111+
}
112+
} else {
113+
toSerialize["{{baseName}}"] = o.{{name}}
114+
}
115+
{{/isNullable}}
116+
{{! if argument is not nullable, don't set it if it is nil}}
117+
{{^isNullable}}
118+
if o.{{name}} != nil {
119+
toSerialize["{{baseName}}"] = o.{{name}}
120+
}
121+
{{/isNullable}}
122+
{{/vars}}
123+
return json.Marshal(toSerialize)
124+
}
125+
126+
{{/isEnum}}
127+
42128
{{/model}}
43129
{{/models}}

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

+42-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,50 @@
44

55
Name | Type | Description | Notes
66
------------ | ------------- | ------------- | -------------
7-
{{#vars}}**{{name}}** | {{#isNullable}}Pointer to {{/isNullable}}{{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{{dataType}}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
7+
{{#vars}}**{{name}}** | Pointer to {{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{{dataType}}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
88
{{/vars}}
99

10+
{{^isEnum}}
11+
## Methods
12+
13+
{{#vars}}
14+
### Get{{name}}
15+
16+
`func (o *{{classname}}) Get{{name}}() {{dataType}}`
17+
18+
Get{{name}} returns the {{name}} field if non-nil, zero value otherwise.
19+
20+
### Get{{name}}Ok
21+
22+
`func (o *{{classname}}) Get{{name}}Ok() ({{dataType}}, bool)`
23+
24+
Get{{name}}Ok returns a tuple with the {{name}} field if it's non-nil, zero value otherwise
25+
and a boolean to check if the value has been set.
26+
27+
### Has{{name}}
28+
29+
`func (o *{{classname}}) Has{{name}}() bool`
30+
31+
Has{{name}} returns a boolean if a field has been set.
32+
33+
### Set{{name}}
34+
35+
`func (o *{{classname}}) Set{{name}}(v {{dataType}})`
36+
37+
Set{{name}} gets a reference to the given {{dataType}} and assigns it to the {{name}} field.
38+
39+
{{#isNullable}}
40+
### Set{{name}}ExplicitNull
41+
42+
`func (o *{{classname}}) Set{{name}}ExplicitNull(b bool)`
43+
44+
Set{{name}}ExplicitNull (un)sets {{name}} to be considered as explicit "null" value
45+
when serializing to JSON (pass true as argument to set this, false to unset)
46+
The {{name}} value is set to nil even if false is passed
47+
{{/isNullable}}
48+
{{/vars}}
49+
{{/isEnum}}
50+
1051
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
1152

1253
{{/model}}{{/models}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{{>partial_header}}
2+
package {{packageName}}
3+
4+
import "time"
5+
6+
// Bool is a helper routine that returns a pointer to given integer value.
7+
func Bool(v bool) *bool { return &v }
8+
9+
// Int is a helper routine that returns a pointer to given integer value.
10+
func Int(v int) *int { return &v }
11+
12+
// Int32 is a helper routine that returns a pointer to given integer value.
13+
func Int32(v int32) *int32 { return &v }
14+
15+
// Int64 is a helper routine that returns a pointer to given integer value.
16+
func Int64(v int64) *int64 { return &v }
17+
18+
// Float is a helper routine that returns a pointer to given float value.
19+
func Float(v float32) *float32 { return &v }
20+
21+
// Float32 is a helper routine that returns a pointer to given float value.
22+
func Float32(v float32) *float32 { return &v }
23+
24+
// Float64 is a helper routine that returns a pointer to given float value.
25+
func Float64(v float64) *float64 { return &v }
26+
27+
// String is a helper routine that returns a pointer to given string value.
28+
func String(v string) *string { return &v }
29+
30+
// Time is helper routine that returns a pointer to given Time value.
31+
func Time(v time.Time) *time.Time { return &v }

samples/client/petstore/go/auth_test.go

+18-12
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ func TestOAuth2(t *testing.T) {
3737
tokenSource := cfg.TokenSource(createContext(nil), &tok)
3838
auth := context.WithValue(context.Background(), sw.ContextOAuth2, tokenSource)
3939

40-
newPet := (sw.Pet{Id: 12992, Name: "gopher",
41-
PhotoUrls: []string{"http://1.com", "http://2.com"}, Status: "pending", Tags: []sw.Tag{sw.Tag{Id: 1, Name: "tag2"}}})
40+
newPet := (sw.Pet{Id: sw.Int64(12992), Name: sw.String("gopher"),
41+
PhotoUrls: &[]string{"http://1.com", "http://2.com"}, Status: sw.String("pending"),
42+
Tags: &[]sw.Tag{sw.Tag{Id: sw.Int64(1), Name: sw.String("tag2")}}})
4243

4344
r, err := client.PetApi.AddPet(context.Background(), newPet)
4445

@@ -73,8 +74,9 @@ func TestBasicAuth(t *testing.T) {
7374
Password: "f4k3p455",
7475
})
7576

76-
newPet := (sw.Pet{Id: 12992, Name: "gopher",
77-
PhotoUrls: []string{"http://1.com", "http://2.com"}, Status: "pending", Tags: []sw.Tag{sw.Tag{Id: 1, Name: "tag2"}}})
77+
newPet := (sw.Pet{Id: sw.Int64(12992), Name: sw.String("gopher"),
78+
PhotoUrls: &[]string{"http://1.com", "http://2.com"}, Status: sw.String("pending"),
79+
Tags: &[]sw.Tag{sw.Tag{Id: sw.Int64(1), Name: sw.String("tag2")}}})
7880

7981
r, err := client.PetApi.AddPet(auth, newPet)
8082

@@ -104,8 +106,9 @@ func TestBasicAuth(t *testing.T) {
104106
func TestAccessToken(t *testing.T) {
105107
auth := context.WithValue(context.Background(), sw.ContextAccessToken, "TESTFAKEACCESSTOKENISFAKE")
106108

107-
newPet := (sw.Pet{Id: 12992, Name: "gopher",
108-
PhotoUrls: []string{"http://1.com", "http://2.com"}, Status: "pending", Tags: []sw.Tag{sw.Tag{Id: 1, Name: "tag2"}}})
109+
newPet := (sw.Pet{Id: sw.Int64(12992), Name: sw.String("gopher"),
110+
PhotoUrls: &[]string{"http://1.com", "http://2.com"}, Status: sw.String("pending"),
111+
Tags: &[]sw.Tag{sw.Tag{Id: sw.Int64(1), Name: sw.String("tag2")}}})
109112

110113
r, err := client.PetApi.AddPet(nil, newPet)
111114

@@ -135,8 +138,9 @@ func TestAccessToken(t *testing.T) {
135138
func TestAPIKeyNoPrefix(t *testing.T) {
136139
auth := context.WithValue(context.Background(), sw.ContextAPIKey, sw.APIKey{Key: "TEST123"})
137140

138-
newPet := (sw.Pet{Id: 12992, Name: "gopher",
139-
PhotoUrls: []string{"http://1.com", "http://2.com"}, Status: "pending", Tags: []sw.Tag{sw.Tag{Id: 1, Name: "tag2"}}})
141+
newPet := (sw.Pet{Id: sw.Int64(12992), Name: sw.String("gopher"),
142+
PhotoUrls: &[]string{"http://1.com", "http://2.com"}, Status: sw.String("pending"),
143+
Tags: &[]sw.Tag{sw.Tag{Id: sw.Int64(1), Name: sw.String("tag2")}}})
140144

141145
r, err := client.PetApi.AddPet(context.Background(), newPet)
142146

@@ -172,8 +176,9 @@ func TestAPIKeyNoPrefix(t *testing.T) {
172176
func TestAPIKeyWithPrefix(t *testing.T) {
173177
auth := context.WithValue(context.Background(), sw.ContextAPIKey, sw.APIKey{Key: "TEST123", Prefix: "Bearer"})
174178

175-
newPet := (sw.Pet{Id: 12992, Name: "gopher",
176-
PhotoUrls: []string{"http://1.com", "http://2.com"}, Status: "pending", Tags: []sw.Tag{sw.Tag{Id: 1, Name: "tag2"}}})
179+
newPet := (sw.Pet{Id: sw.Int64(12992), Name: sw.String("gopher"),
180+
PhotoUrls: &[]string{"http://1.com", "http://2.com"}, Status: sw.String("pending"),
181+
Tags: &[]sw.Tag{sw.Tag{Id: sw.Int64(1), Name: sw.String("tag2")}}})
177182

178183
r, err := client.PetApi.AddPet(nil, newPet)
179184

@@ -208,8 +213,9 @@ func TestAPIKeyWithPrefix(t *testing.T) {
208213

209214
func TestDefaultHeader(t *testing.T) {
210215

211-
newPet := (sw.Pet{Id: 12992, Name: "gopher",
212-
PhotoUrls: []string{"http://1.com", "http://2.com"}, Status: "pending", Tags: []sw.Tag{sw.Tag{Id: 1, Name: "tag2"}}})
216+
newPet := (sw.Pet{Id: sw.Int64(12992), Name: sw.String("gopher"),
217+
PhotoUrls: &[]string{"http://1.com", "http://2.com"}, Status: sw.String("pending"),
218+
Tags: &[]sw.Tag{sw.Tag{Id: sw.Int64(1), Name: sw.String("tag2")}}})
213219

214220
r, err := client.PetApi.AddPet(context.Background(), newPet)
215221

samples/client/petstore/go/fake_api_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ func TestPutBodyWithFileSchema(t *testing.T) {
1414
return // early return to test compilation
1515

1616
schema := sw.FileSchemaTestClass{
17-
File: sw.File{SourceURI: "https://example.com/image.png"},
18-
Files: []sw.File{{SourceURI: "https://example.com/image.png"}}}
17+
File: &sw.File{SourceURI: sw.String("https://example.com/image.png")},
18+
Files: &[]sw.File{{SourceURI: sw.String("https://example.com/image.png")}}}
1919

2020
r, err := client.FakeApi.TestBodyWithFileSchema(context.Background(), schema)
2121

samples/client/petstore/go/go-petstore-withXml/docs/AdditionalPropertiesAnyType.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,35 @@
44

55
Name | Type | Description | Notes
66
------------ | ------------- | ------------- | -------------
7-
**Name** | **string** | | [optional]
7+
**Name** | Pointer to **string** | | [optional]
8+
9+
## Methods
10+
11+
### GetName
12+
13+
`func (o *AdditionalPropertiesAnyType) GetName() string`
14+
15+
GetName returns the Name field if non-nil, zero value otherwise.
16+
17+
### GetNameOk
18+
19+
`func (o *AdditionalPropertiesAnyType) GetNameOk() (string, bool)`
20+
21+
GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise
22+
and a boolean to check if the value has been set.
23+
24+
### HasName
25+
26+
`func (o *AdditionalPropertiesAnyType) HasName() bool`
27+
28+
HasName returns a boolean if a field has been set.
29+
30+
### SetName
31+
32+
`func (o *AdditionalPropertiesAnyType) SetName(v string)`
33+
34+
SetName gets a reference to the given string and assigns it to the Name field.
35+
836

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

samples/client/petstore/go/go-petstore-withXml/docs/AdditionalPropertiesArray.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,35 @@
44

55
Name | Type | Description | Notes
66
------------ | ------------- | ------------- | -------------
7-
**Name** | **string** | | [optional]
7+
**Name** | Pointer to **string** | | [optional]
8+
9+
## Methods
10+
11+
### GetName
12+
13+
`func (o *AdditionalPropertiesArray) GetName() string`
14+
15+
GetName returns the Name field if non-nil, zero value otherwise.
16+
17+
### GetNameOk
18+
19+
`func (o *AdditionalPropertiesArray) GetNameOk() (string, bool)`
20+
21+
GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise
22+
and a boolean to check if the value has been set.
23+
24+
### HasName
25+
26+
`func (o *AdditionalPropertiesArray) HasName() bool`
27+
28+
HasName returns a boolean if a field has been set.
29+
30+
### SetName
31+
32+
`func (o *AdditionalPropertiesArray) SetName(v string)`
33+
34+
SetName gets a reference to the given string and assigns it to the Name field.
35+
836

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

0 commit comments

Comments
 (0)