encoding/openapi: few tweaks in the output

- use oneOf instead of anyOf, as all values are
  derived from proto anyway for now.
- don't include empty list default

Change-Id: Ifd22e6f8bbd7d168123d00cc596cd7bb83ac517f
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2349
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/encoding/openapi/build.go b/encoding/openapi/build.go
index 8d64cee..3ba94c0 100644
--- a/encoding/openapi/build.go
+++ b/encoding/openapi/build.go
@@ -72,6 +72,9 @@
 	for i.Next() {
 		// message, enum, or constant.
 		label := i.Label()
+		if c.isInternal(label) {
+			continue
+		}
 		c.schemas.Set(label, c.build(label, i.Value()))
 	}
 	return comps, nil
@@ -81,9 +84,16 @@
 	return newRootBuilder(c).schema(name, v)
 }
 
+// isInternal reports whether or not to include this type.
+func (c *buildContext) isInternal(name string) bool {
+	// TODO: allow a regexp filter in Config. If we have closed structs and
+	// definitions, this will likely be unnecessary.
+	return strings.HasSuffix(name, "_value")
+}
+
 // shouldExpand reports is the given identifier is not exported.
 func (c *buildContext) shouldExpand(name string) bool {
-	return c.expandRefs
+	return c.expandRefs || c.isInternal(name)
 }
 
 func (b *builder) failf(v cue.Value, format string, args ...interface{}) {
@@ -115,6 +125,7 @@
 
 func (b *builder) value(v cue.Value, f typeFunc) {
 	count := 0
+	disallowDefault := false
 	var values cue.Value
 	if b.ctx.shouldExpand(strings.Join(v.Reference(), ".")) {
 		values = v
@@ -126,6 +137,7 @@
 			switch r := v.Reference(); {
 			case r != nil:
 				b.addRef(r)
+				disallowDefault = true
 			default:
 				count++
 				values = values.Unify(v)
@@ -165,9 +177,20 @@
 		}
 	}
 
-	if v, ok := v.Default(); ok && v.IsConcrete() {
-		v.Default()
-		b.set("default", v)
+	if v, ok := v.Default(); ok && v.IsConcrete() && !disallowDefault {
+		// TODO: should we show the empty list default? This would be correct
+		// but perhaps a bit too pedantic and noisy.
+		switch {
+		case v.Kind() == cue.ListKind:
+			iter, _ := v.List()
+			if !iter.Next() {
+				// Don't show default for empty list.
+				break
+			}
+			fallthrough
+		default:
+			b.set("default", v)
+		}
 	}
 }
 
@@ -273,7 +296,9 @@
 			anyOf = append(anyOf, c.finish())
 		}
 
-		b.set("anyOf", anyOf)
+		// TODO: analyze CUE structs to figure out if it should be oneOf or
+		// anyOf. As the source is protobuf for now, it is always oneOf.
+		b.set("oneOf", anyOf)
 		if nullable {
 			b.set("nullable", true)
 		}
@@ -569,7 +594,7 @@
 		// - maxLength
 		// - minLength
 
-	case cue.NoOp:
+	case cue.NoOp, cue.SelectorOp:
 		// TODO: determine formats from specific types.
 
 	default:
@@ -600,7 +625,7 @@
 		// - maxLength
 		// - minLength
 
-	case cue.NoOp:
+	case cue.NoOp, cue.SelectorOp:
 
 	default:
 		b.failf(v, "unsupported op %v for bytes type", op)
diff --git a/encoding/openapi/testdata/oneof.json b/encoding/openapi/testdata/oneof.json
index b805d2e..c526b28 100644
--- a/encoding/openapi/testdata/oneof.json
+++ b/encoding/openapi/testdata/oneof.json
@@ -3,7 +3,7 @@
    "components": {
       "schema": {
          "MyString": {
-            "anyOf": [
+            "oneOf": [
                {
                   "type": "object",
                   "required": [
@@ -46,8 +46,7 @@
                   "type": "array",
                   "items": {
                      "$ref": "#/components/schema/MyString"
-                  },
-                  "default": []
+                  }
                },
                "include": {
                   "$ref": "#/components/schema/MyString"
diff --git a/encoding/openapi/testdata/openapi-norefs.json b/encoding/openapi/testdata/openapi-norefs.json
index 075be6b..0094bd8 100644
--- a/encoding/openapi/testdata/openapi-norefs.json
+++ b/encoding/openapi/testdata/openapi-norefs.json
@@ -16,8 +16,7 @@
                         "type": "array",
                         "items": {
                            "type": "string"
-                        },
-                        "default": []
+                        }
                      },
                      "foo": {
                         "type": "number",
@@ -35,8 +34,7 @@
                               "type": "array",
                               "items": {
                                  "type": "integer"
-                              },
-                              "default": []
+                              }
                            },
                            "port": {
                               "type": "integer"
@@ -47,7 +45,7 @@
                },
                {
                   "type": "object",
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -89,8 +87,7 @@
                   "type": "array",
                   "items": {
                      "type": "integer"
-                  },
-                  "default": []
+                  }
                },
                "port": {
                   "type": "integer"
@@ -103,7 +100,7 @@
             "maximum": 2147483647
          },
          "YourMessage": {
-            "anyOf": [
+            "oneOf": [
                {
                   "type": "object",
                   "required": [
@@ -137,7 +134,7 @@
          "YourMessage2": {
             "allOf": [
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -163,7 +160,7 @@
                   ]
                },
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -189,7 +186,7 @@
                   ]
                },
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -217,7 +214,7 @@
             ]
          },
          "Msg2": {
-            "anyOf": [
+            "oneOf": [
                {
                   "type": "object",
                   "required": [
@@ -263,7 +260,7 @@
          "DefaultStruct": {
             "allOf": [
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -275,8 +272,7 @@
                               "type": "array",
                               "items": {
                                  "type": "integer"
-                              },
-                              "default": []
+                              }
                            },
                            "port": {
                               "type": "integer"
diff --git a/encoding/openapi/testdata/openapi.json b/encoding/openapi/testdata/openapi.json
index c6cc8cb..7409a75 100644
--- a/encoding/openapi/testdata/openapi.json
+++ b/encoding/openapi/testdata/openapi.json
@@ -16,8 +16,7 @@
                         "type": "array",
                         "items": {
                            "type": "string"
-                        },
-                        "default": []
+                        }
                      },
                      "foo": {
                         "allOf": [
@@ -39,7 +38,7 @@
                },
                {
                   "type": "object",
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -81,8 +80,7 @@
                   "type": "array",
                   "items": {
                      "type": "integer"
-                  },
-                  "default": []
+                  }
                },
                "port": {
                   "type": "integer"
@@ -95,7 +93,7 @@
             "maximum": 2147483647
          },
          "YourMessage": {
-            "anyOf": [
+            "oneOf": [
                {
                   "type": "object",
                   "required": [
@@ -129,7 +127,7 @@
          "YourMessage2": {
             "allOf": [
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -155,7 +153,7 @@
                   ]
                },
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -181,7 +179,7 @@
                   ]
                },
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "type": "object",
                         "required": [
@@ -209,7 +207,7 @@
             ]
          },
          "Msg2": {
-            "anyOf": [
+            "oneOf": [
                {
                   "type": "object",
                   "required": [
@@ -255,7 +253,7 @@
          "DefaultStruct": {
             "allOf": [
                {
-                  "anyOf": [
+                  "oneOf": [
                      {
                         "$ref": "#/components/schema/Port"
                      },