diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java index bedd7ed652a8..38e6419238cd 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractGoCodegen.java @@ -92,8 +92,8 @@ public AbstractGoCodegen() { "complex128", "rune", "byte", - "map[string]interface{}", - "interface{}" + "ObjectType", + "AnyType" ) ); @@ -128,9 +128,15 @@ public AbstractGoCodegen() { // map[string]interface{}, whereas an arbitrary type is implemented // in golang as interface{}. // See issue #5387 for more details. - typeMapping.put("object", "map[string]interface{}"); - typeMapping.put("interface{}", "interface{}"); - typeMapping.put("AnyType", "interface{}"); + typeMapping.put("object", "ObjectType"); + // A schema that does not specify the 'type' attribute. The value + // can be anything. + typeMapping.put("AnyType", "AnyType"); + // Below is the entry to map the JSON 'null' type to golang. + // Note there is no built-in 'null' type in golang, and it's not possible + // to declare a variable whose only possible value is 'nil'. + // For example `a := nil` is not a valid go statement. + typeMapping.put("null", "NullType"); numberTypes = new HashSet( Arrays.asList( @@ -391,7 +397,7 @@ public String getSchemaType(Schema p) { type = openAPIType; } else if ("object".equals(openAPIType) && ModelUtils.isAnyTypeSchema(p)) { // Arbitrary type. Note this is not the same thing as free-form object. - type = "interface{}"; + type = "AnyType"; } else if (typeMapping.containsKey(openAPIType)) { type = typeMapping.get(openAPIType); if (languageSpecificPrimitives.contains(type)) @@ -598,14 +604,58 @@ private void setExportParameterName(List codegenParameters) { } } + /** + * OAS type mapping to golang implementation: + * + * AnyType interface{} Any type, e.g. null, string, integer, number, boolean, map, array. + * ObjectType map[string]interface{} Free-form object with no constraint on additional properties. + * map[string]Animal map[string]Animal Free-form object. The value of undeclared properties must be 'Animal'. + * map[string]ObjectType map[string]map[string]interface{} Free-form object. The value of undeclared properties must be an object (map). + * map[string][]interface{} Free-form object. The value of undeclared properties must be an array. + * + */ @Override public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { - // The 'go-experimental/model.mustache' template conditionally generates accessor methods. - // For primitive types and custom types (e.g. interface{}, map[string]interface{}...), - // the generated code has a wrapper type and a Get() function to access the underlying type. - // For containers (e.g. Array, Map), the generated code returns the type directly. - if (property.isContainer || property.isFreeFormObject || property.isAnyType) { - property.vendorExtensions.put("x-golang-is-container", true); + // The 'go-experimental/model.mustache' template generates accessor methods. + // For containers (e.g. Array, Map) and non-nullable primitive types, the go struct field + // is the underlying type, e.g. *int32, *string, *bool... + // In other cases (nullable primitive types, free-form objects...), the generated code has + // a wrapper type and a Get() function to access the underlying type. + boolean hasWrapper = false; + if (property.isAnyType) { + // The wrapper type is the 'AnyType' struct and the wrapped type is 'interface{}'. + hasWrapper = true; + } else if (property.isFreeFormObject && !property.isNullable) { // && + // Undeclared properties use case. + // The undeclared properties are implemented using a go map. + // The map key is always a string. + // The map value is interface{} when there are no constraints, but the + // 'additionalProperties' attribute may require a specific type. + if (property.items == null) { + // The 'additionalProperties' attribute is not set, so it is a free-form object + // with no constraint on the type of undeclared properties. + // The wrapper type is 'ObjectType'. + // The wrapped type is 'map[string]interface{}'. + hasWrapper = true; + } else if (property.items.isFreeFormObject && !property.items.isNullable) { + // The 'additionalProperties' attribute is set, and the value of the undeclared + // properties must be a free-form object. Hence it's a map of map. + // The wrapper type is map[string]ObjectType. + // The wrapped type is 'map[string]map[string]interface{}'. + hasWrapper = true; + } else { + // The 'additionalProperties' attribute is set, and the value of the undeclared + // properties is not free-form. For example, if the undeclared properties must + // be of type 'Animal', then: + // The wrapper type is map[string]Animal. + // The wrapped type is 'map[string]Animal'. + } + } else if (property.isNullable && !property.isContainer) { + // Primitive types. + hasWrapper = true; + } + if (hasWrapper) { + property.vendorExtensions.put("x-golang-has-wrapper", true); } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java index 0bea07e4dba7..69e013eb74a2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/GoClientExperimentalCodegen.java @@ -177,11 +177,37 @@ public Map postProcessModels(Map objs) { } for (CodegenProperty param : model.vars) { + // Two golang types are used in the generated code: the type of the + // struct fields and the types of the getter and setter methods. + // The struct fields may use a wrapper type (such as 'NullableBool'), + // whereas the getter method returns the unwrapped type (e.g. 'bool'). + // param.dataType is the golang type of the generated struct field. + // "x-go-base-type" is the type in the setter and getter functions. param.vendorExtensions.put("x-go-base-type", param.dataType); - if (!param.isNullable || param.isMapContainer || param.isListContainer || - param.isFreeFormObject || param.isAnyType) { + if (!param.vendorExtensions.containsKey("x-golang-has-wrapper")) { continue; } + if (param.isAnyType) { + param.vendorExtensions.put("x-go-base-type", "interface{}"); + continue; + } else if (param.isFreeFormObject) { + switch (param.dataType) { + case "ObjectType": + param.vendorExtensions.put("x-go-base-type", "map[string]interface{}"); + continue; + case "[]ObjectType": + param.vendorExtensions.put("x-go-base-type", "map[string][]interface{}"); + continue; + case "map[string]ObjectType": + param.vendorExtensions.put("x-go-base-type", "map[string]map[string]interface{}"); + continue; + } + } + /* + if (!param.isNullable || param.isMapContainer || param.isListContainer) { + continue; + } + */ if (param.isDateTime) { // Note this could have been done by adding the following line in processOpts(), // however, we only want to represent the DateTime object as NullableTime if diff --git a/modules/openapi-generator/src/main/resources/go-experimental/model.mustache b/modules/openapi-generator/src/main/resources/go-experimental/model.mustache index 91a0d12b3149..76cbb8ef562c 100644 --- a/modules/openapi-generator/src/main/resources/go-experimental/model.mustache +++ b/modules/openapi-generator/src/main/resources/go-experimental/model.mustache @@ -69,16 +69,16 @@ func New{{classname}}({{#vars}}{{#required}}{{nameInCamelCase}} {{dataType}}, {{ {{/required}} {{^required}} {{#defaultValue}} -{{^vendorExtensions.x-golang-is-container}} {{#isNullable}} +{{#vendorExtensions.x-golang-has-wrapper}} var {{nameInCamelCase}} {{{datatypeWithEnum}}} = {{{.}}} this.{{name}} = *New{{{dataType}}}(&{{nameInCamelCase}}) +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} var {{nameInCamelCase}} {{{dataType}}} = {{{.}}} this.{{name}} = &{{nameInCamelCase}} {{/isNullable}} -{{/vendorExtensions.x-golang-is-container}} {{/defaultValue}} {{/required}} {{/vars}} @@ -92,17 +92,17 @@ func New{{classname}}WithDefaults() *{{classname}} { this := {{classname}}{} {{#vars}} {{#defaultValue}} -{{^vendorExtensions.x-golang-is-container}} {{#isNullable}} +{{#vendorExtensions.x-golang-has-wrapper}} {{!we use datatypeWithEnum here, since it will represent the non-nullable name of the datatype, e.g. int64 for NullableInt64}} var {{nameInCamelCase}} {{{datatypeWithEnum}}} = {{{.}}} this.{{name}} = *New{{{dataType}}}(&{{nameInCamelCase}}) +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} var {{nameInCamelCase}} {{{dataType}}} = {{{.}}} this.{{name}} = {{^required}}&{{/required}}{{nameInCamelCase}} {{/isNullable}} -{{/vendorExtensions.x-golang-is-container}} {{/defaultValue}} {{/vars}} return &this @@ -115,21 +115,26 @@ func New{{classname}}WithDefaults() *{{classname}} { // If the value is explicit nil, the zero value for {{vendorExtensions.x-go-base-type}} will be returned {{/isNullable}} func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { - if o == nil {{#isNullable}}{{^vendorExtensions.x-golang-is-container}}|| o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { + if o == nil {{#isNullable}}{{#vendorExtensions.x-golang-has-wrapper}}|| o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-has-wrapper}}{{/isNullable}} { var ret {{vendorExtensions.x-go-base-type}} return ret } {{#isNullable}} -{{#vendorExtensions.x-golang-is-container}} +{{^vendorExtensions.x-golang-has-wrapper}} return o.{{name}} -{{/vendorExtensions.x-golang-is-container}} -{{^vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} +{{#vendorExtensions.x-golang-has-wrapper}} return *o.{{name}}.Get() -{{/vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} +{{#vendorExtensions.x-golang-has-wrapper}} + return o.{{name}}.Get() +{{/vendorExtensions.x-golang-has-wrapper}} +{{^vendorExtensions.x-golang-has-wrapper}} return o.{{name}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} } @@ -139,31 +144,36 @@ func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { // NOTE: If the value is an explicit nil, `nil, true` will be returned {{/isNullable}} func (o *{{classname}}) Get{{name}}Ok() (*{{vendorExtensions.x-go-base-type}}, bool) { - if o == nil {{#isNullable}}{{#vendorExtensions.x-golang-is-container}}|| o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { + if o == nil {{#isNullable}}{{^vendorExtensions.x-golang-has-wrapper}}|| o.{{name}} == nil{{/vendorExtensions.x-golang-has-wrapper}}{{/isNullable}} { return nil, false } {{#isNullable}} -{{#vendorExtensions.x-golang-is-container}} +{{^vendorExtensions.x-golang-has-wrapper}} return &o.{{name}}, true -{{/vendorExtensions.x-golang-is-container}} -{{^vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} +{{#vendorExtensions.x-golang-has-wrapper}} return o.{{name}}.Get(), o.{{name}}.IsSet() -{{/vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} +{{#vendorExtensions.x-golang-has-wrapper}} + return &o.{{name}}.Get(), true +{{/vendorExtensions.x-golang-has-wrapper}} +{{^vendorExtensions.x-golang-has-wrapper}} return &o.{{name}}, true +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} } // Set{{name}} sets field value func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}}) { {{#isNullable}} -{{#vendorExtensions.x-golang-is-container}} +{{^vendorExtensions.x-golang-has-wrapper}} o.{{name}} = v -{{/vendorExtensions.x-golang-is-container}} -{{^vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} +{{#vendorExtensions.x-golang-has-wrapper}} o.{{name}}.Set(&v) -{{/vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} o.{{name}} = v @@ -174,20 +184,25 @@ func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}}) { {{^required}} // Get{{name}} returns the {{name}} field value if set, zero value otherwise{{#isNullable}} (both if not set or set to explicit null){{/isNullable}}. func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { - if o == nil {{^isNullable}}|| o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{^vendorExtensions.x-golang-is-container}}|| o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { + if o == nil {{^isNullable}}|| o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-has-wrapper}}|| o.{{name}}.Get() == nil{{/vendorExtensions.x-golang-has-wrapper}}{{/isNullable}} { var ret {{vendorExtensions.x-go-base-type}} return ret } {{#isNullable}} -{{#vendorExtensions.x-golang-is-container}} +{{^vendorExtensions.x-golang-has-wrapper}} return o.{{name}} -{{/vendorExtensions.x-golang-is-container}} -{{^vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} +{{#vendorExtensions.x-golang-has-wrapper}} return *o.{{name}}.Get() -{{/vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} +{{#vendorExtensions.x-golang-has-wrapper}} + return *o.{{name}}.Get() +{{/vendorExtensions.x-golang-has-wrapper}} +{{^vendorExtensions.x-golang-has-wrapper}} return *o.{{name}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} } @@ -197,25 +212,30 @@ func (o *{{classname}}) Get{{name}}() {{vendorExtensions.x-go-base-type}} { // NOTE: If the value is an explicit nil, `nil, true` will be returned {{/isNullable}} func (o *{{classname}}) Get{{name}}Ok() (*{{vendorExtensions.x-go-base-type}}, bool) { - if o == nil {{^isNullable}}|| o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}}|| o.{{name}} == nil{{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { + if o == nil {{^isNullable}}|| o.{{name}} == nil{{/isNullable}}{{#isNullable}}{{^vendorExtensions.x-golang-has-wrapper}}|| o.{{name}} == nil{{/vendorExtensions.x-golang-has-wrapper}}{{/isNullable}} { return nil, false } {{#isNullable}} -{{#vendorExtensions.x-golang-is-container}} +{{^vendorExtensions.x-golang-has-wrapper}} return &o.{{name}}, true -{{/vendorExtensions.x-golang-is-container}} -{{^vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} +{{#vendorExtensions.x-golang-has-wrapper}} return o.{{name}}.Get(), o.{{name}}.IsSet() -{{/vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} +{{#vendorExtensions.x-golang-has-wrapper}} + return o.{{name}}.Get(), true +{{/vendorExtensions.x-golang-has-wrapper}} +{{^vendorExtensions.x-golang-has-wrapper}} return o.{{name}}, true +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} } // Has{{name}} returns a boolean if a field has been set. func (o *{{classname}}) Has{{name}}() bool { - if o != nil && {{^isNullable}}o.{{name}} != nil{{/isNullable}}{{#isNullable}}{{#vendorExtensions.x-golang-is-container}}o.{{name}} != nil{{/vendorExtensions.x-golang-is-container}}{{^vendorExtensions.x-golang-is-container}}o.{{name}}.IsSet(){{/vendorExtensions.x-golang-is-container}}{{/isNullable}} { + if o != nil && {{^isNullable}}o.{{name}} != nil{{/isNullable}}{{#isNullable}}{{^vendorExtensions.x-golang-has-wrapper}}o.{{name}} != nil{{/vendorExtensions.x-golang-has-wrapper}}{{#vendorExtensions.x-golang-has-wrapper}}o.{{name}}.IsSet(){{/vendorExtensions.x-golang-has-wrapper}}{{/isNullable}} { return true } @@ -225,19 +245,24 @@ func (o *{{classname}}) Has{{name}}() bool { // Set{{name}} gets a reference to the given {{dataType}} and assigns it to the {{name}} field. func (o *{{classname}}) Set{{name}}(v {{vendorExtensions.x-go-base-type}}) { {{#isNullable}} -{{#vendorExtensions.x-golang-is-container}} +{{^vendorExtensions.x-golang-has-wrapper}} o.{{name}} = v -{{/vendorExtensions.x-golang-is-container}} -{{^vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} +{{#vendorExtensions.x-golang-has-wrapper}} o.{{name}}.Set(&v) -{{/vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{^isNullable}} +{{#vendorExtensions.x-golang-has-wrapper}} + o.{{name}}.Set(&v) +{{/vendorExtensions.x-golang-has-wrapper}} +{{^vendorExtensions.x-golang-has-wrapper}} o.{{name}} = &v +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} } {{#isNullable}} -{{^vendorExtensions.x-golang-is-container}} +{{#vendorExtensions.x-golang-has-wrapper}} // Set{{name}}Nil sets the value for {{name}} to be an explicit nil func (o *{{classname}}) Set{{name}}Nil() { o.{{name}}.Set(nil) @@ -247,7 +272,7 @@ func (o *{{classname}}) Set{{name}}Nil() { func (o *{{classname}}) Unset{{name}}() { o.{{name}}.Unset() } -{{/vendorExtensions.x-golang-is-container}} +{{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{/required}} @@ -269,17 +294,17 @@ func (o {{classname}}) MarshalJSON() ([]byte, error) { {{#vars}} {{! if argument is nullable, only serialize it if it is set}} {{#isNullable}} - {{#vendorExtensions.x-golang-is-container}} + {{^vendorExtensions.x-golang-has-wrapper}} {{! support for container fields is not ideal at this point because of lack of Nullable* types}} if o.{{name}} != nil { toSerialize["{{baseName}}"] = o.{{name}} } - {{/vendorExtensions.x-golang-is-container}} - {{^vendorExtensions.x-golang-is-container}} + {{/vendorExtensions.x-golang-has-wrapper}} + {{#vendorExtensions.x-golang-has-wrapper}} if {{#required}}true{{/required}}{{^required}}o.{{name}}.IsSet(){{/required}} { toSerialize["{{baseName}}"] = o.{{name}}.Get() } - {{/vendorExtensions.x-golang-is-container}} + {{/vendorExtensions.x-golang-has-wrapper}} {{/isNullable}} {{! if argument is not nullable, don't set it if it is nil}} {{^isNullable}} @@ -326,6 +351,7 @@ func (s *{{classname}}) UnmarshalJSON(src []byte) error { {{/discriminator}} {{^discriminator}} {{#oneOf}} + {{! TODO: validate the payload against the JSON schema. Relying on golang JSON unmarshaling is not sufficient to determine the payload validates against the schema}} var unmarshaled{{{.}}} *{{{.}}} = &{{{.}}}{} err = json.Unmarshal(src, unmarshaled{{{.}}}) if err == nil { diff --git a/modules/openapi-generator/src/main/resources/go-experimental/utils.mustache b/modules/openapi-generator/src/main/resources/go-experimental/utils.mustache index 89e00e0267be..a2b033a80046 100644 --- a/modules/openapi-generator/src/main/resources/go-experimental/utils.mustache +++ b/modules/openapi-generator/src/main/resources/go-experimental/utils.mustache @@ -2,7 +2,9 @@ package {{packageName}} import ( + "bytes" "encoding/json" + "errors" "time" ) @@ -30,6 +32,121 @@ func PtrString(v string) *string { return &v } // PtrTime is helper routine that returns a pointer to given Time value. func PtrTime(v time.Time) *time.Time { return &v } +var nullLiteral []byte = []byte("null") + +// NullType is a type whose only value can be the JSON 'null' value. +type NullType struct{ + isSet bool +} + +func NewNullType() *NullType { + return nil +} + +func (v NullType) Get() interface{} { + return nil +} + +func (v *NullType) Set() { + v.isSet = true +} + +func (v NullType) IsSet() bool { + return v.isSet +} + +func (v *NullType) Unset() { + v.isSet = false +} + +func (v NullType) MarshalJSON() ([]byte, error) { + return nullLiteral, nil +} + +func (v *NullType) UnmarshalJSON(src []byte) error { + if bytes.Equal(bytes.TrimSpace(nullLiteral), src) { + v.isSet = true + return nil + } + return errors.New("Cannot unmarshal value into 'null' type") +} + +// AnyType is a type whose value can any valid OpenAPI type. +// The value may be the null value, a string, integer, number, boolean, array +// or object. +type AnyType struct{ + value *interface{} + isSet bool +} + +func NewAnyType(val *interface{}) *AnyType { + return &AnyType{value: val, isSet: true} +} + +func (v AnyType) Get() *interface{} { + return v.value +} + +func (v *AnyType) Set(val *interface{}) { + v.value = val + v.isSet = true +} + +func (v AnyType) IsSet() bool { + return v.isSet +} + +func (v *AnyType) Unset() { + v.isSet = false +} + +func (v AnyType) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *AnyType) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +// ObjectType is a type whose value can be any OpenAPI object with undeclared properties. +type ObjectType struct{ + value *map[string]interface{} + isSet bool +} + +// NewObjectType creates and returns an object with the specified map +// of undeclared properties. +func NewObjectType(val *map[string]interface{}) *ObjectType { + return &ObjectType{value: val, isSet: true} +} + +func (v ObjectType) Get() *map[string]interface{} { + return v.value +} + +func (v *ObjectType) Set(val *map[string]interface{}) { + v.value = val + v.isSet = true +} + +func (v ObjectType) IsSet() bool { + return v.isSet +} + +func (v *ObjectType) Unset() { + v.isSet = false +} + +func (v ObjectType) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *ObjectType) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + type NullableBool struct { value *bool isSet bool diff --git a/modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml b/modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml index 74598c6ce709..3e779d042413 100644 --- a/modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml @@ -1250,22 +1250,32 @@ components: type: integer format: int32 description: User Status - arbitraryObject: + objectWithNoDeclaredProps: type: object description: test code generation for objects Value must be a map of strings to values. It cannot be the 'null' value. - arbitraryNullableObject: + objectWithNoDeclaredPropsNullable: type: object description: test code generation for nullable objects. Value must be a map of strings to values or the 'null' value. nullable: true - arbitraryTypeValue: + anyTypeProp: description: test code generation for any type - Value can be any type - string, number, boolean, array or object. - arbitraryNullableTypeValue: + Here the 'type' attribute is not specified, which means the value can be anything, + including the null value, string, number, boolean, array or object. + See https://github.com/OAI/OpenAPI-Specification/issues/1389 + # TODO: this should be supported, currently there are some issues in the code generation. + #anyTypeExceptNullProp: + # description: any type except 'null' + # Here the 'type' attribute is not specified, which means the value can be anything, + # including the null value, string, number, boolean, array or object. + # not: + # type: 'null' + anyTypePropNullable: description: test code generation for any type - Value can be any type - string, number, boolean, array, object or - the 'null' value. + Here the 'type' attribute is not specified, which means the value can be anything, + including the null value, string, number, boolean, array or object. + The 'nullable' attribute does not change the allowed values. nullable: true xml: name: User @@ -1855,6 +1865,7 @@ components: - $ref: '#/components/schemas/banana' fruitReq: oneOf: + - type: 'null' - $ref: '#/components/schemas/appleReq' - $ref: '#/components/schemas/bananaReq' appleReq: