From b6fc7ae61163cac673360734a5c0bd4bdd0964eb Mon Sep 17 00:00:00 2001 From: Jens Gersdorf Date: Fri, 3 Jun 2022 22:01:05 +0200 Subject: [PATCH 1/3] [ISSUE-609] add outSchema.SkipOptionalPointer = true for interface{} see https://github.com/deepmap/oapi-codegen/issues/609 --- pkg/codegen/schema.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index b0f8daff37..93016a5348 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -266,6 +266,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { // If we don't even have the object designator, we're a completely // generic type. outType = "interface{}" + outSchema.SkipOptionalPointer = true } outSchema.GoType = outType outSchema.DefineViaAlias = true From db4a0964b1abd3c504ee638c85a75916bb436515 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Sat, 10 May 2025 18:37:00 +0100 Subject: [PATCH 2/3] sq --- internal/test/issues/issue609/config.yaml | 7 +++ internal/test/issues/issue609/generate.go | 3 ++ internal/test/issues/issue609/issue609.gen.go | 9 ++++ .../test/issues/issue609/issue609_test.go | 54 +++++++++++++++++++ internal/test/issues/issue609/openapi.yaml | 11 ++++ pkg/codegen/schema.go | 1 + 6 files changed, 85 insertions(+) create mode 100644 internal/test/issues/issue609/config.yaml create mode 100644 internal/test/issues/issue609/generate.go create mode 100644 internal/test/issues/issue609/issue609.gen.go create mode 100644 internal/test/issues/issue609/issue609_test.go create mode 100644 internal/test/issues/issue609/openapi.yaml diff --git a/internal/test/issues/issue609/config.yaml b/internal/test/issues/issue609/config.yaml new file mode 100644 index 0000000000..a9c4b93879 --- /dev/null +++ b/internal/test/issues/issue609/config.yaml @@ -0,0 +1,7 @@ +# yaml-language-server: $schema=../../../../configuration-schema.json +package: issue609 +generate: + models: true +output: issue609.gen.go +output-options: + skip-prune: true diff --git a/internal/test/issues/issue609/generate.go b/internal/test/issues/issue609/generate.go new file mode 100644 index 0000000000..ade5eb92fb --- /dev/null +++ b/internal/test/issues/issue609/generate.go @@ -0,0 +1,3 @@ +package issue609 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml openapi.yaml diff --git a/internal/test/issues/issue609/issue609.gen.go b/internal/test/issues/issue609/issue609.gen.go new file mode 100644 index 0000000000..a5d76e500d --- /dev/null +++ b/internal/test/issues/issue609/issue609.gen.go @@ -0,0 +1,9 @@ +// Package issue609 provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. +package issue609 + +// ResponseBody defines model for ResponseBody. +type ResponseBody struct { + Unknown interface{} `json:"unknown,omitempty"` +} diff --git a/internal/test/issues/issue609/issue609_test.go b/internal/test/issues/issue609/issue609_test.go new file mode 100644 index 0000000000..b0a5bf8679 --- /dev/null +++ b/internal/test/issues/issue609/issue609_test.go @@ -0,0 +1,54 @@ +package issue609 + +import ( + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" +) + +func TestGeneratedCode(t *testing.T) { + t.Run("For an object", func(t *testing.T) { + t.Run("A required field should be a non-pointer", func(t *testing.T) { + theType := TypeWithOptionalField{ + AtRequired: uuid.New(), + } + + require.NotZero(t, theType.AtRequired) + }) + + t.Run("An optional field with x-go-type-skip-optional-pointer should be a non-pointer", func(t *testing.T) { + theType := TypeWithOptionalField{ + AtRequired: uuid.New(), + } + + require.NotZero(t, theType.AtRequired) + }) + }) + + t.Run("For a query parameter", func(t *testing.T) { + t.Run("An optional field with x-go-type-skip-optional-pointer should be a non-pointer", func(t *testing.T) { + + u := uuid.New() + + theType := GetRootParams{ + At: u, + } + + require.NotZero(t, theType.At) + }) + }) + + t.Run("For a field with an AllOf", func(t *testing.T) { + t.Run("An optional field with x-go-type-skip-optional-pointer should be a non-pointer", func(t *testing.T) { + + u := uuid.New() + + theType := TypeWithAllOf{ + Id: u, + } + + require.NotZero(t, theType.Id) + }) + }) +} diff --git a/internal/test/issues/issue609/openapi.yaml b/internal/test/issues/issue609/openapi.yaml new file mode 100644 index 0000000000..d7dae7fdf3 --- /dev/null +++ b/internal/test/issues/issue609/openapi.yaml @@ -0,0 +1,11 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: "Referencing an optional field, which has no information about the type it is will generate an `interface{}`, without the 'optional pointer'" +paths: +components: + schemas: + ResponseBody: + type: object + properties: + unknown: {} diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index d185ca2b32..9ca303d91b 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -329,6 +329,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { // If we don't even have the object designator, we're a completely // generic type. outType = "interface{}" + // this should never have an "optional pointer", as it doesn't make sense to be a `*interface{}` outSchema.SkipOptionalPointer = true } outSchema.GoType = outType From 8b22ae44b70550a7e851c1c8270de683ce82aaae Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Sat, 10 May 2025 18:38:00 +0100 Subject: [PATCH 3/3] sq --- .../test/issues/issue609/issue609_test.go | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 internal/test/issues/issue609/issue609_test.go diff --git a/internal/test/issues/issue609/issue609_test.go b/internal/test/issues/issue609/issue609_test.go deleted file mode 100644 index b0a5bf8679..0000000000 --- a/internal/test/issues/issue609/issue609_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package issue609 - -import ( - "testing" - - "github.com/google/uuid" - "github.com/stretchr/testify/require" -) - -func TestGeneratedCode(t *testing.T) { - t.Run("For an object", func(t *testing.T) { - t.Run("A required field should be a non-pointer", func(t *testing.T) { - theType := TypeWithOptionalField{ - AtRequired: uuid.New(), - } - - require.NotZero(t, theType.AtRequired) - }) - - t.Run("An optional field with x-go-type-skip-optional-pointer should be a non-pointer", func(t *testing.T) { - theType := TypeWithOptionalField{ - AtRequired: uuid.New(), - } - - require.NotZero(t, theType.AtRequired) - }) - }) - - t.Run("For a query parameter", func(t *testing.T) { - t.Run("An optional field with x-go-type-skip-optional-pointer should be a non-pointer", func(t *testing.T) { - - u := uuid.New() - - theType := GetRootParams{ - At: u, - } - - require.NotZero(t, theType.At) - }) - }) - - t.Run("For a field with an AllOf", func(t *testing.T) { - t.Run("An optional field with x-go-type-skip-optional-pointer should be a non-pointer", func(t *testing.T) { - - u := uuid.New() - - theType := TypeWithAllOf{ - Id: u, - } - - require.NotZero(t, theType.Id) - }) - }) -}