Repository: ogen-go/ogen (go)

Issue:
bug: implicit mapping does not work
```yaml
components:
  schemas:
    JobNothing:
      description: Do nothing
      required:
        - type
      properties:
        type:
          type: string
    JobDownload:
      description: Download chunk
      required:
        - type
        - date
      properties:
        type:
          type: string
        date:
          type: string
          format: datetime
    Job:
      description: job to perform on worker
      discriminator:
        propertyName: "type"
      oneOf:
        - $ref: "#/components/schemas/JobNothing"
        - $ref: "#/components/schemas/JobDownload"
```

```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x683761]

goroutine 1 [running]:
github.com/ogen-go/ogen/internal/gen.(*schemaGen).generate(0xc0002657e8, {0xc000266f90, 0x1000057c6b20a10}, 0xc000186640)
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/internal/gen/schema_gen.go:205 +0x1c21
github.com/ogen-go/ogen/internal/gen.(*Generator).generateSchema(0xc0000f82c0, {0xc000266f90, 0xd}, 0x10)
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/internal/gen/gen_schema.go:14 +0x9a
github.com/ogen-go/ogen/internal/gen.(*Generator).responseToIR(0xc0000f82c0, {0xc000266f90, 0xc000265b30}, {0xc000021940, 0x2}, 0xc0002568b8)
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/internal/gen/gen_responses.go:151 +0x845
github.com/ogen-go/ogen/internal/gen.(*Generator).generateResponses(0xc0000f82c0, {0xc000266eb0, 0xb}, 0xc000272390)
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/internal/gen/gen_responses.go:34 +0x39b
github.com/ogen-go/ogen/internal/gen.(*Generator).generateOperation(0x0, 0xc0000ae9c0)
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/internal/gen/gen_operation.go:37 +0x296
github.com/ogen-go/ogen/internal/gen.(*Generator).makeIR(0xc0000f82c0, {0xc000010848, 0x0, 0xc000265da0})
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/internal/gen/generator.go:78 +0xac
github.com/ogen-go/ogen/internal/gen.NewGenerator(0x0, {{0x0, 0x0}, {0xc000272380, 0x1, 0x1}})
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/internal/gen/generator.go:58 +0x1f5
main.main()
        /go/pkg/mod/github.com/ogen-go/ogen@v0.0.0-20211124110652-5733f5a38197/cmd/ogen/main.go:100 +0x48c
exit status 2
gen.go:3: running "go": exit status 1
```

Pull request:
fix(gen): remove nil pointer dereference
Fix #60

Patch:
diff --git a/internal/gen/schema_gen.go b/internal/gen/schema_gen.go
index 242b8d34..3e87efd6 100644
--- a/internal/gen/schema_gen.go
+++ b/internal/gen/schema_gen.go
@@ -182,11 +182,21 @@ func (g *schemaGen) generate(name string, schema *oas.Schema) (*ir.Type, error)
 		}
 		if d := schema.Discriminator; d != nil {
 			sum.SumSpec.Discriminator = schema.Discriminator.PropertyName
+			getRef := func(s *ir.Type) string {
+				// HACK(ernado): refactor
+				if s.Schema != nil && s.Schema.Ref != "" {
+					return s.Schema.Ref
+				}
+				if s.AliasTo != nil && s.AliasTo.Schema != nil && s.AliasTo.Schema.Ref != "" {
+					return s.AliasTo.Schema.Ref
+				}
+				panic("unable to find reference")
+			}
 			for k, v := range schema.Discriminator.Mapping {
 				// Explicit mapping.
 				var found bool
 				for _, s := range sum.SumOf {
-					if path.Base(s.Schema.Ref) == v {
+					if path.Base(getRef(s)) == v {
 						found = true
 						sum.SumSpec.Mapping = append(sum.SumSpec.Mapping, ir.SumSpecMap{
 							Key:  k,
@@ -202,7 +212,7 @@ func (g *schemaGen) generate(name string, schema *oas.Schema) (*ir.Type, error)
 				// Implicit mapping, defaults to type name.
 				for _, s := range sum.SumOf {
 					sum.SumSpec.Mapping = append(sum.SumSpec.Mapping, ir.SumSpecMap{
-						Key:  path.Base(s.Schema.Ref),
+						Key:  path.Base(getRef(s)),
 						Type: s.Name,
 					})
 				}


Test patch:
diff --git a/_testdata/err_oneof_explicit.yaml b/_testdata/err_oneof_explicit.yaml
new file mode 100644
index 00000000..78b9c819
--- /dev/null
+++ b/_testdata/err_oneof_explicit.yaml
@@ -0,0 +1,67 @@
+openapi: 3.0.3
+info:
+  title: Go Faster Github Archive Coordinator
+  description: Coordinates Archive Workers
+  version: 0.1.0
+servers:
+  - url: 'https://localhost:8080'
+paths:
+  /job/poll:
+    post:
+      description: Request job from coordinator
+      parameters:
+        - name: token
+          in: query
+          required: true
+          description: Worker token
+      responses:
+        200:
+          description: Job is available
+          content:
+            "application/json":
+              schema:
+                $ref: "#/components/schemas/Job"
+components:
+  responses:
+    Error:
+      description: "Error while processing request"
+      content:
+        "application/json":
+          schema:
+            $ref: "#/components/schemas/Error"
+  schemas:
+    Error:
+      type: object
+      description: "error description"
+      properties:
+        message:
+          type: string
+      required: [ message ]
+    JobNothing:
+      description: Do nothing
+      required:
+        - type
+      properties:
+        type:
+          type: string
+    JobDownload:
+      description: Download chunk
+      required:
+        - type
+        - date
+      properties:
+        type:
+          type: string
+        date:
+          type: string
+          format: datetime
+    Job:
+      description: job to perform on worker
+      discriminator:
+        propertyName: "type"
+        mapping:
+          "nothing": "JobNothing"
+          "download": "JobDownload"
+      oneOf:
+        - $ref: "#/components/schemas/JobNothing"
+        - $ref: "#/components/schemas/JobDownload"
diff --git a/_testdata/err_oneof_implicit.yaml b/_testdata/err_oneof_implicit.yaml
new file mode 100644
index 00000000..35754e6d
--- /dev/null
+++ b/_testdata/err_oneof_implicit.yaml
@@ -0,0 +1,64 @@
+openapi: 3.0.3
+info:
+  title: Go Faster Github Archive Coordinator
+  description: Coordinates Archive Workers
+  version: 0.1.0
+servers:
+  - url: 'https://localhost:8080'
+paths:
+  /job/poll:
+    post:
+      description: Request job from coordinator
+      parameters:
+        - name: token
+          in: query
+          required: true
+          description: Worker token
+      responses:
+        200:
+          description: Job is available
+          content:
+            "application/json":
+              schema:
+                $ref: "#/components/schemas/Job"
+components:
+  responses:
+    Error:
+      description: "Error while processing request"
+      content:
+        "application/json":
+          schema:
+            $ref: "#/components/schemas/Error"
+  schemas:
+    Error:
+      type: object
+      description: "error description"
+      properties:
+        message:
+          type: string
+      required: [ message ]
+    JobNothing:
+      description: Do nothing
+      required:
+        - type
+      properties:
+        type:
+          type: string
+    JobDownload:
+      description: Download chunk
+      required:
+        - type
+        - date
+      properties:
+        type:
+          type: string
+        date:
+          type: string
+          format: datetime
+    Job:
+      description: job to perform on worker
+      discriminator:
+        propertyName: "type"
+      oneOf:
+        - $ref: "#/components/schemas/JobNothing"
+        - $ref: "#/components/schemas/JobDownload"
diff --git a/gen_test.go b/gen_test.go
index c29a8488..41d0c455 100644
--- a/gen_test.go
+++ b/gen_test.go
@@ -85,4 +85,10 @@ func TestGenerate(t *testing.T) {
 		"sum type parameter",
 		"unsupported content types",
 	))
+	t.Run("Regression", func(t *testing.T) {
+		t.Run("OneOf", func(t *testing.T) {
+			t.Run("Explicit", g("err_oneof_explicit.yaml"))
+			t.Run("Implicit", g("err_oneof_implicit.yaml"))
+		})
+	})
 }