Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 1 | // Copyright 2019 CUE Authors |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package protobuf |
| 16 | |
Marcel van Lohuizen | fbcb339 | 2019-06-25 11:02:21 +0200 | [diff] [blame] | 17 | import ( |
| 18 | "text/scanner" |
| 19 | |
| 20 | "github.com/emicklei/proto" |
| 21 | ) |
Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 22 | |
| 23 | func protoToCUE(typ string, options []*proto.Option) (ref string, ok bool) { |
| 24 | t, ok := scalars[typ] |
| 25 | return t, ok |
| 26 | } |
| 27 | |
| 28 | var scalars = map[string]string{ |
| 29 | // Differing |
| 30 | "sint32": "int32", |
| 31 | "sint64": "int64", |
| 32 | "fixed32": "uint32", |
| 33 | "fixed64": "uint64", |
| 34 | "sfixed32": "int32", |
| 35 | "sfixed64": "int64", |
| 36 | |
| 37 | // Identical to CUE |
| 38 | "int32": "int32", |
| 39 | "int64": "int64", |
| 40 | "uint32": "uint32", |
| 41 | "uint64": "uint64", |
| 42 | |
| 43 | "double": "float64", |
| 44 | "float": "float32", |
| 45 | |
| 46 | "bool": "bool", |
| 47 | "string": "string", |
| 48 | "bytes": "bytes", |
| 49 | } |
| 50 | |
Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 51 | func (p *protoConverter) setBuiltin(from, to string, pkg *protoConverter) { |
Marcel van Lohuizen | 93e9597 | 2019-06-27 16:47:52 +0200 | [diff] [blame] | 52 | p.scope[0][from] = mapping{to, "", pkg} |
Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 53 | } |
| 54 | |
Marcel van Lohuizen | 64cb20a | 2019-08-06 21:24:14 +0200 | [diff] [blame] | 55 | var ( |
Marcel van Lohuizen | 13c9718 | 2019-08-13 13:39:50 +0200 | [diff] [blame] | 56 | pkgTime = &protoConverter{cuePkgPath: "time"} |
| 57 | pkgStruct = &protoConverter{cuePkgPath: "struct"} |
Marcel van Lohuizen | 64cb20a | 2019-08-06 21:24:14 +0200 | [diff] [blame] | 58 | ) |
| 59 | |
Marcel van Lohuizen | d8f4450 | 2019-08-01 15:05:02 +0200 | [diff] [blame] | 60 | func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, required bool) (generate bool) { |
Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 61 | // Map some builtin types to their JSON/CUE mappings. |
| 62 | switch file { |
| 63 | case "gogoproto/gogo.proto": |
| 64 | |
Marcel van Lohuizen | d8f4450 | 2019-08-01 15:05:02 +0200 | [diff] [blame] | 65 | case "google/protobuf/struct.proto": |
| 66 | p.setBuiltin("google.protobuf.Struct", "{}", nil) |
| 67 | p.setBuiltin("google.protobuf.Value", "_", nil) |
| 68 | p.setBuiltin("google.protobuf.NullValue", "null", nil) |
| 69 | p.setBuiltin("google.protobuf.ListValue", "[...]", nil) |
| 70 | p.setBuiltin("google.protobuf.StringValue", "string", nil) |
| 71 | p.setBuiltin("google.protobuf.BoolValue", "bool", nil) |
| 72 | p.setBuiltin("google.protobuf.NumberValue", "number", nil) |
| 73 | return false |
| 74 | |
Marcel van Lohuizen | 64cb20a | 2019-08-06 21:24:14 +0200 | [diff] [blame] | 75 | case "google/protobuf/empty.proto": |
| 76 | p.setBuiltin("google.protobuf.Empty", "struct.MaxFields(0)", pkgStruct) |
| 77 | return false |
Marcel van Lohuizen | d8f4450 | 2019-08-01 15:05:02 +0200 | [diff] [blame] | 78 | |
Marcel van Lohuizen | 64cb20a | 2019-08-06 21:24:14 +0200 | [diff] [blame] | 79 | case "google/protobuf/duration.proto": |
| 80 | p.setBuiltin("google.protobuf.Duration", "time.Duration", pkgTime) |
| 81 | return false |
Marcel van Lohuizen | d8f4450 | 2019-08-01 15:05:02 +0200 | [diff] [blame] | 82 | |
Marcel van Lohuizen | 64cb20a | 2019-08-06 21:24:14 +0200 | [diff] [blame] | 83 | case "google/protobuf/timestamp.proto": |
| 84 | p.setBuiltin("google.protobuf.Timestamp", "time.Time", pkgTime) |
| 85 | return false |
Marcel van Lohuizen | d8f4450 | 2019-08-01 15:05:02 +0200 | [diff] [blame] | 86 | |
Marcel van Lohuizen | 743365e | 2019-08-11 15:21:06 +0200 | [diff] [blame] | 87 | case "google/protobuf/any.proto": |
| 88 | // TODO: technically, the value should be `_` (anything), but that |
| 89 | // will not convert to a valid OpenAPI value. In practice, all |
| 90 | // "well-known" types except wrapper types (which will likely not |
| 91 | // be used here) are represented as strings. |
| 92 | // |
| 93 | // In Structural OpenAPI this type cannot be represented. |
| 94 | p.setBuiltin("google.protobuf.Any", `{ |
| 95 | // 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 `+ |
| 96 | "`type.googleapis.com/google.protobuf.Duration`"+`). The name should be in a canonical form (e.g., leading "." is not accepted). |
| 97 | // 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. |
| 98 | "@type": string, |
| 99 | }`, nil) |
| 100 | return false |
| 101 | |
| 102 | case "google/protobuf/wrappers.proto": |
| 103 | p.setBuiltin("google.protobuf.DoubleValue", `null | float`, nil) |
| 104 | p.setBuiltin("google.protobuf.FloatValue", `null | float`, nil) |
| 105 | p.setBuiltin("google.protobuf.Int64Value", `null | int64`, nil) |
| 106 | p.setBuiltin("google.protobuf.UInt64Value", `null | uint64`, nil) |
| 107 | p.setBuiltin("google.protobuf.Int32Value", `null | int32`, nil) |
| 108 | p.setBuiltin("google.protobuf.UInt32Value", `null | uint32`, nil) |
| 109 | p.setBuiltin("google.protobuf.BoolValue", `null | bool`, nil) |
| 110 | p.setBuiltin("google.protobuf.StringValue", `null | string`, nil) |
| 111 | p.setBuiltin("google.protobuf.BytesValue", `null | bytes`, nil) |
| 112 | return false |
| 113 | |
Marcel van Lohuizen | 64cb20a | 2019-08-06 21:24:14 +0200 | [diff] [blame] | 114 | // case "google/protobuf/field_mask.proto": |
| 115 | // p.setBuiltin("google.protobuf.FieldMask", "protobuf.FieldMask", nil) |
| 116 | |
| 117 | // protobuf.Any |
Marcel van Lohuizen | d8f4450 | 2019-08-01 15:05:02 +0200 | [diff] [blame] | 118 | |
Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 119 | default: |
Marcel van Lohuizen | 9fe5fed | 2019-06-25 13:04:40 +0200 | [diff] [blame] | 120 | if required { |
| 121 | failf(pos, "import %q not found", file) |
| 122 | } |
Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 123 | } |
Marcel van Lohuizen | d8f4450 | 2019-08-01 15:05:02 +0200 | [diff] [blame] | 124 | return true |
Marcel van Lohuizen | 5274e98 | 2019-04-28 17:51:43 +0200 | [diff] [blame] | 125 | } |