Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
encoding/openapi: finalise when constructing openapi AST
Browse files Browse the repository at this point in the history
When building OpenAPI enums from a CUE instance, specifically one that
contains an enum imported from protobuf, we don't care about the
definition-encoded integer enum value (introduced as part of dcfff00).
Instead we only care about the final value of the enum.

Prior to dcfff00, an imported protobuf enum would look like this:

    #CaptureMode: "DEFAULT" | "IPTABLES" | "NONE"

Post dcfff00, it looks like:

    #CaptureMode: {
            "DEFAULT"
            #enumValue: 0
    } | {
            "IPTABLES"
            #enumValue: 1
    } | {
            "NONE"
            #enumValue: 2
    }

Therefore, in the process of building an enum we simply need to finalise
the CUE Value prior to deriving its syntax.

The test as part of this CL comes from a real Istio schema that
uncovered this bug in the first place.

Fixes #977

Change-Id: I5b4cbb2f35b0535488d8f77b1e2166f89ed2644d
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9843
Reviewed-by: CUE cueckoo <[email protected]>
Reviewed-by: Marcel van Lohuizen <[email protected]>
  • Loading branch information
myitcv committed May 18, 2021
1 parent d5041a1 commit 13a4d3c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 2 deletions.
4 changes: 2 additions & 2 deletions encoding/openapi/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1301,10 +1301,10 @@ func (b *builder) inta(v cue.Value, offset int64) ast.Expr {

func (b *builder) decode(v cue.Value) ast.Expr {
v, _ = v.Default()
return v.Syntax().(ast.Expr)
return v.Syntax(cue.Final()).(ast.Expr)
}

func (b *builder) big(v cue.Value) ast.Expr {
v, _ = v.Default()
return v.Syntax().(ast.Expr)
return v.Syntax(cue.Final()).(ast.Expr)
}
25 changes: 25 additions & 0 deletions encoding/openapi/openapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ func TestParseDefinitions(t *testing.T) {
"array.cue",
"array.json",
defaultConfig,
}, {
"enum.cue",
"enum.json",
defaultConfig,
}, {
"struct.cue",
"struct.json",
Expand Down Expand Up @@ -140,6 +144,12 @@ func TestParseDefinitions(t *testing.T) {
t.Fatal(errors.Details(inst.Err, nil))
}

all, err := tc.config.All(inst)
if err != nil {
t.Fatal(err)
}
walk(all)

b, err := openapi.Gen(inst, tc.config)
if err != nil {
t.Fatal(err)
Expand All @@ -165,6 +175,21 @@ func TestParseDefinitions(t *testing.T) {
}
}

// walk traverses an openapi.OrderedMap. This is a helper function
// used to ensure that a generated OpenAPI value is well-formed.
func walk(om *openapi.OrderedMap) {
for _, p := range om.Pairs() {
switch p := p.Value.(type) {
case *openapi.OrderedMap:
walk(p)
case []*openapi.OrderedMap:
for _, om := range p {
walk(om)
}
}
}
}

// This is for debugging purposes. Do not remove.
func TestX(t *testing.T) {
t.Skip()
Expand Down
10 changes: 10 additions & 0 deletions encoding/openapi/testdata/enum.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#CaptureMode: {
"DEFAULT"
#enumValue: 0
} | {
"IPTABLES"
#enumValue: 1
} | {
"NONE"
#enumValue: 2
}
20 changes: 20 additions & 0 deletions encoding/openapi/testdata/enum.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"openapi": "3.0.0",
"info": {
"title": "Generated by cue.",
"version": "no version"
},
"paths": {},
"components": {
"schemas": {
"CaptureMode": {
"type": "string",
"enum": [
"DEFAULT",
"IPTABLES",
"NONE"
]
}
}
}
}

0 comments on commit 13a4d3c

Please sign in to comment.