1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package protobuf
16
17 import (
18 "fmt"
19 "text/scanner"
20
21 "cuelang.org/go/cue/ast"
22 "cuelang.org/go/cue/parser"
23 "cuelang.org/go/cue/token"
24 "github.com/emicklei/proto"
25 )
26
27 func protoToCUE(typ string, options []*proto.Option) ast.Expr {
28 t, ok := scalars[typ]
29 if !ok {
30 return nil
31 }
32 return predeclared(t)
33 }
34
35 var scalars = map[string]string{
36
37 "sint32": "int32",
38 "sint64": "int64",
39 "fixed32": "uint32",
40 "fixed64": "uint64",
41 "sfixed32": "int32",
42 "sfixed64": "int64",
43
44
45 "int32": "int32",
46 "int64": "int64",
47 "uint32": "uint32",
48 "uint64": "uint64",
49
50 "double": "float64",
51 "float": "float32",
52
53 "bool": "bool",
54 "string": "string",
55 "bytes": "bytes",
56 }
57
58 func predeclared(s string) ast.Expr {
59 return &ast.Ident{
60 Name: s,
61 Node: ast.NewIdent("__" + s),
62 }
63 }
64
65 func (p *protoConverter) setBuiltin(from string, to func() ast.Expr, pkg *protoConverter) {
66 p.scope[0][from] = mapping{to, pkg}
67 }
68
69 func (p *protoConverter) setBuiltinParse(from, to string, pkg *protoConverter) {
70 f := func() ast.Expr {
71 expr, err := parser.ParseExpr("", to, parser.ParseComments)
72 if err != nil {
73 panic(fmt.Sprintf("error parsing name %q: %v", to, err))
74 }
75 return expr
76 }
77 p.scope[0][from] = mapping{f, pkg}
78 }
79
80 var (
81 pkgTime = &protoConverter{cuePkgPath: "time"}
82 pkgStruct = &protoConverter{cuePkgPath: "struct"}
83 importTime = ast.NewImport(nil, "time")
84 importStruct = ast.NewImport(nil, "struct")
85 )
86
87 func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, required bool) (generate bool) {
88
89 switch file {
90 case "gogoproto/gogo.proto":
91
92 case "google/protobuf/struct.proto":
93 p.setBuiltin("google.protobuf.Struct", func() ast.Expr {
94 return ast.NewStruct()
95 }, nil)
96
97 p.setBuiltin("google.protobuf.Value", func() ast.Expr {
98 return ast.NewIdent("_")
99 }, nil)
100
101 p.setBuiltin("google.protobuf.NullValue", func() ast.Expr {
102 return ast.NewNull()
103 }, nil)
104
105 p.setBuiltin("google.protobuf.ListValue", func() ast.Expr {
106 return ast.NewList(&ast.Ellipsis{})
107 }, nil)
108
109 p.setBuiltin("google.protobuf.StringValue", func() ast.Expr {
110 return predeclared("string")
111 }, nil)
112
113 p.setBuiltin("google.protobuf.BoolValue", func() ast.Expr {
114 return predeclared("bool")
115 }, nil)
116
117 p.setBuiltin("google.protobuf.NumberValue", func() ast.Expr {
118 return predeclared("number")
119 }, nil)
120
121 return false
122
123 case "google/protobuf/empty.proto":
124 f := func() ast.Expr {
125 time := &ast.Ident{Name: "struct", Node: importStruct}
126 return ast.NewCall(
127 ast.NewSel(time, "MaxFields"),
128 ast.NewLit(token.INT, "0"),
129 )
130 }
131 p.setBuiltin("google.protobuf.Empty", f, pkgStruct)
132 return false
133
134 case "google/protobuf/duration.proto":
135 f := func() ast.Expr {
136 time := &ast.Ident{Name: "time", Node: importTime}
137 return ast.NewSel(time, "Duration")
138 }
139 p.setBuiltin("google.protobuf.Duration", f, pkgTime)
140 return false
141
142 case "google/protobuf/timestamp.proto":
143 f := func() ast.Expr {
144 time := &ast.Ident{Name: "time", Node: importTime}
145 return ast.NewSel(time, "Time")
146 }
147 p.setBuiltin("google.protobuf.Timestamp", f, pkgTime)
148 return false
149
150 case "google/protobuf/any.proto":
151
152
153
154
155
156
157 p.setBuiltinParse("google.protobuf.Any", `{
158 // 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 `+
159 "`type.googleapis.com/google.protobuf.Duration`"+`). The name should be in a canonical form (e.g., leading "." is not accepted).
160 // 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.
161 "@type": string,
162 }`, nil)
163 return false
164
165 case "google/protobuf/wrappers.proto":
166 p.setBuiltinParse("google.protobuf.DoubleValue", `null | float`, nil)
167 p.setBuiltinParse("google.protobuf.FloatValue", `null | float`, nil)
168 p.setBuiltinParse("google.protobuf.Int64Value", `null | int64`, nil)
169 p.setBuiltinParse("google.protobuf.UInt64Value", `null | uint64`, nil)
170 p.setBuiltinParse("google.protobuf.Int32Value", `null | int32`, nil)
171 p.setBuiltinParse("google.protobuf.UInt32Value", `null | uint32`, nil)
172 p.setBuiltinParse("google.protobuf.BoolValue", `null | bool`, nil)
173 p.setBuiltinParse("google.protobuf.StringValue", `null | string`, nil)
174 p.setBuiltinParse("google.protobuf.BytesValue", `null | bytes`, nil)
175 return false
176
177
178
179
180
181
182 default:
183 if required {
184 failf(pos, "import %q not found", file)
185 }
186 }
187 return true
188 }
189
View as plain text