encoding/protobuf: add more proto to JSON conversions

support Any and Wrappers

Change-Id: Ia311e4f3b6d6c172897d896123251d68cdfcf01c
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2780
Reviewed-by: Jason Wang <jasonwzm@google.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/any/any_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/any/any_proto_gen.cue
deleted file mode 100644
index 43f43b9..0000000
--- a/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/any/any_proto_gen.cue
+++ /dev/null
@@ -1,146 +0,0 @@
-
-//  Protocol Buffers - Google's data interchange format
-//  Copyright 2008 Google Inc.  All rights reserved.
-//  https://developers.google.com/protocol-buffers/
-// 
-//  Redistribution and use in source and binary forms, with or without
-//  modification, are permitted provided that the following conditions are
-//  met:
-// 
-//      * Redistributions of source code must retain the above copyright
-//  notice, this list of conditions and the following disclaimer.
-//      * Redistributions in binary form must reproduce the above
-//  copyright notice, this list of conditions and the following disclaimer
-//  in the documentation and/or other materials provided with the
-//  distribution.
-//      * Neither the name of Google Inc. nor the names of its
-//  contributors may be used to endorse or promote products derived from
-//  this software without specific prior written permission.
-// 
-//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-//  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-//  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-//  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-//  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-//  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-package any
-
-//  `Any` contains an arbitrary serialized protocol buffer message along with a
-//  URL that describes the type of the serialized message.
-// 
-//  Protobuf library provides support to pack/unpack Any values in the form
-//  of utility functions or additional generated methods of the Any type.
-// 
-//  Example 1: Pack and unpack a message in C++.
-// 
-//      Foo foo = ...;
-//      Any any;
-//      any.PackFrom(foo);
-//      ...
-//      if (any.UnpackTo(&foo)) {
-//        ...
-//      }
-// 
-//  Example 2: Pack and unpack a message in Java.
-// 
-//      Foo foo = ...;
-//      Any any = Any.pack(foo);
-//      ...
-//      if (any.is(Foo.class)) {
-//        foo = any.unpack(Foo.class);
-//      }
-// 
-//   Example 3: Pack and unpack a message in Python.
-// 
-//      foo = Foo(...)
-//      any = Any()
-//      any.Pack(foo)
-//      ...
-//      if any.Is(Foo.DESCRIPTOR):
-//        any.Unpack(foo)
-//        ...
-// 
-//   Example 4: Pack and unpack a message in Go
-// 
-//       foo := &pb.Foo{...}
-//       any, err := ptypes.MarshalAny(foo)
-//       ...
-//       foo := &pb.Foo{}
-//       if err := ptypes.UnmarshalAny(any, foo); err != nil {
-//         ...
-//       }
-// 
-//  The pack methods provided by protobuf library will by default use
-//  'type.googleapis.com/full.type.name' as the type URL and the unpack
-//  methods only use the fully qualified type name after the last '/'
-//  in the type URL, for example "foo.bar.com/x/y.z" will yield type
-//  name "y.z".
-// 
-// 
-//  JSON
-//  ====
-//  The JSON representation of an `Any` value uses the regular
-//  representation of the deserialized, embedded message, with an
-//  additional field `@type` which contains the type URL. Example:
-// 
-//      package google.profile;
-//      message Person {
-//        string first_name = 1;
-//        string last_name = 2;
-//      }
-// 
-//      {
-//        "@type": "type.googleapis.com/google.profile.Person",
-//        "firstName": <string>,
-//        "lastName": <string>
-//      }
-// 
-//  If the embedded message type is well-known and has a custom JSON
-//  representation, that representation will be embedded adding a field
-//  `value` which holds the custom JSON in addition to the `@type`
-//  field. Example (for message [google.protobuf.Duration][]):
-// 
-//      {
-//        "@type": "type.googleapis.com/google.protobuf.Duration",
-//        "value": "1.212s"
-//      }
-// 
-Any: {
-	//  A URL/resource name that uniquely identifies the type of the serialized
-	//  protocol buffer message. This string must contain at least
-	//  one "/" character. The last segment of the URL's path must represent
-	//  the fully qualified name of the type (as in
-	//  `path/google.protobuf.Duration`). The name should be in a canonical form
-	//  (e.g., leading "." is not accepted).
-	// 
-	//  In practice, teams usually precompile into the binary all types that they
-	//  expect it to use in the context of Any. However, for URLs which use the
-	//  scheme `http`, `https`, or no scheme, one can optionally set up a type
-	//  server that maps type URLs to message definitions as follows:
-	// 
-	//  * If no scheme is provided, `https` is assumed.
-	//  * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-	//    value in binary format, or produce an error.
-	//  * Applications are allowed to cache lookup results based on the
-	//    URL, or have them precompiled into a binary to avoid any
-	//    lookup. Therefore, binary compatibility needs to be preserved
-	//    on changes to types. (Use versioned type names to manage
-	//    breaking changes.)
-	// 
-	//  Note: this functionality is not currently available in the official
-	//  protobuf release, and it is not used for type URLs beginning with
-	//  type.googleapis.com.
-	// 
-	//  Schemes other than `http`, `https` (or the empty scheme) might be
-	//  used with implementation specific semantics.
-	// 
-	typeUrl?: string @protobuf(1,name=type_url)
-
-	//  Must be a valid serialized protocol buffer of the above specified type.
-	value?: bytes @protobuf(2)
-}
diff --git a/encoding/protobuf/testdata/istio.io/api/pkg/google.golang.org/genproto/googleapis/rpc/status/status_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/pkg/google.golang.org/genproto/googleapis/rpc/status/status_proto_gen.cue
index f8e8246..fe83de2 100644
--- a/encoding/protobuf/testdata/istio.io/api/pkg/google.golang.org/genproto/googleapis/rpc/status/status_proto_gen.cue
+++ b/encoding/protobuf/testdata/istio.io/api/pkg/google.golang.org/genproto/googleapis/rpc/status/status_proto_gen.cue
@@ -14,8 +14,6 @@
 //  limitations under the License.
 package status
 
-import "github.com/golang/protobuf/ptypes/any"
-
 //  The `Status` type defines a logical error model that is suitable for
 //  different programming environments, including REST APIs and RPC APIs. It is
 //  used by [gRPC](https://github.com/grpc). The error model is designed to be:
@@ -82,5 +80,9 @@
 
 	//  A list of messages that carry the error details.  There is a common set of
 	//  message types for APIs to use.
-	details?: [...any.Any] @protobuf(3,type=google.protobuf.Any)
+	details?: [...{
+		// A URL/resource name that uniquely identifies the type of the serialized protocol buffer message. This string must contain at least one "/" character. The last segment of the URL's path must represent the fully qualified name of the type (as in `type.googleapis.com/google.protobuf.Duration`). The name should be in a canonical form (e.g., leading "." is not accepted).
+		// The remaining fields of this object correspond to fields of the proto messsage. If the embedded message is well-known and has a custom JSON representation, that representation is assigned to the 'value' field.
+		"@type": string
+	}] @protobuf(3,type=google.protobuf.Any)
 }
diff --git a/encoding/protobuf/types.go b/encoding/protobuf/types.go
index 5fff043..2191afe 100644
--- a/encoding/protobuf/types.go
+++ b/encoding/protobuf/types.go
@@ -84,6 +84,33 @@
 		p.setBuiltin("google.protobuf.Timestamp", "time.Time", pkgTime)
 		return false
 
+	case "google/protobuf/any.proto":
+		// TODO: technically, the value should be `_` (anything), but that
+		// will not convert to a valid OpenAPI value. In practice, all
+		// "well-known" types except wrapper types (which will likely not
+		// be used here) are represented as strings.
+		//
+		// In Structural OpenAPI this type cannot be represented.
+		p.setBuiltin("google.protobuf.Any", `{
+	// A URL/resource name that uniquely identifies the type of the serialized protocol buffer message. This string must contain at least one "/" character. The last segment of the URL's path must represent the fully qualified name of the type (as in `+
+			"`type.googleapis.com/google.protobuf.Duration`"+`). The name should be in a canonical form (e.g., leading "." is not accepted).
+	// The remaining fields of this object correspond to fields of the proto messsage. If the embedded message is well-known and has a custom JSON representation, that representation is assigned to the 'value' field.
+	"@type": string,
+}`, nil)
+		return false
+
+	case "google/protobuf/wrappers.proto":
+		p.setBuiltin("google.protobuf.DoubleValue", `null | float`, nil)
+		p.setBuiltin("google.protobuf.FloatValue", `null | float`, nil)
+		p.setBuiltin("google.protobuf.Int64Value", `null | int64`, nil)
+		p.setBuiltin("google.protobuf.UInt64Value", `null | uint64`, nil)
+		p.setBuiltin("google.protobuf.Int32Value", `null | int32`, nil)
+		p.setBuiltin("google.protobuf.UInt32Value", `null | uint32`, nil)
+		p.setBuiltin("google.protobuf.BoolValue", `null | bool`, nil)
+		p.setBuiltin("google.protobuf.StringValue", `null | string`, nil)
+		p.setBuiltin("google.protobuf.BytesValue", `null | bytes`, nil)
+		return false
+
 	// case "google/protobuf/field_mask.proto":
 	// 	p.setBuiltin("google.protobuf.FieldMask", "protobuf.FieldMask", nil)