this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

encoding/protobuf/textproto: add decoder implementation

Note that this is incredibly buggy. Not much I can do,
as there just doesn't seem to be any good textproto parser
for Go, and this one is the recommended "gold standard".

Issue #5

Change-Id: Ieab0910dc4ea6072d9dc50e2947d8a7fb33ba7ef
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9369
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>

+1031 -4
+142
encoding/protobuf/pbinternal/attribute.go
··· 1 + // Copyright 2021 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 pbinternal 16 + 17 + import ( 18 + "strings" 19 + 20 + "cuelang.org/go/cue" 21 + ) 22 + 23 + type CompositeType int 24 + 25 + const ( 26 + Normal CompositeType = iota 27 + List 28 + Map 29 + ) 30 + 31 + type ValueType int 32 + 33 + const ( 34 + Unknown ValueType = iota 35 + Message 36 + Int 37 + Float 38 + String 39 + Bytes 40 + Bool 41 + ) 42 + 43 + type Info struct { 44 + Name string 45 + CUEName string 46 + Attr cue.Attribute 47 + Value cue.Value 48 + 49 + CompositeType CompositeType 50 + ValueType ValueType 51 + Type string 52 + 53 + // For maps only 54 + KeyType ValueType // only for maps 55 + KeyTypeString string 56 + } 57 + 58 + func FromIter(i *cue.Iterator) (info Info, err error) { 59 + return FromValue(i.Label(), i.Value()) 60 + } 61 + 62 + func FromValue(name string, v cue.Value) (info Info, err error) { 63 + a := v.Attribute("protobuf") 64 + 65 + info.Name = name 66 + info.CUEName = name 67 + 68 + if a.Err() == nil { 69 + info.Attr = a 70 + 71 + s, ok, err := a.Lookup(1, "name") 72 + if err != nil { 73 + return info, err 74 + } 75 + if ok { 76 + info.Name = strings.TrimSpace(s) 77 + } 78 + 79 + info.Type, err = a.String(1) 80 + if err != nil { 81 + return info, err 82 + } 83 + } 84 + 85 + switch v.IncompleteKind() { 86 + case cue.ListKind: 87 + info.CompositeType = List 88 + e, _ := v.Elem() 89 + if e.Exists() { 90 + v = e 91 + } else { 92 + for i, _ := v.List(); i.Next(); { 93 + v = i.Value() 94 + break 95 + } 96 + } 97 + 98 + case cue.StructKind: 99 + if strings.HasPrefix(info.Type, "map[") { 100 + a := strings.SplitN(info.Type[len("map["):], ",", 2) 101 + info.KeyTypeString = strings.TrimSpace(a[0]) 102 + switch info.KeyTypeString { 103 + case "string": 104 + info.KeyType = String 105 + case "bytes": 106 + info.KeyType = Bytes 107 + case "double", "float": 108 + info.KeyType = Float 109 + case "bool": 110 + info.KeyType = Bool 111 + default: 112 + info.KeyType = Int // Assuming 113 + } 114 + info.CompositeType = Map 115 + v, _ = v.Elem() 116 + } 117 + } 118 + 119 + info.Value = v 120 + 121 + switch v.IncompleteKind() { 122 + case cue.StructKind: 123 + info.ValueType = Message 124 + 125 + case cue.StringKind: 126 + info.ValueType = String 127 + 128 + case cue.BytesKind: 129 + info.ValueType = Bytes 130 + 131 + case cue.BoolKind: 132 + info.ValueType = Bool 133 + 134 + case cue.IntKind: 135 + info.ValueType = Int 136 + 137 + case cue.FloatKind, cue.NumberKind: 138 + info.ValueType = Float 139 + } 140 + 141 + return info, nil 142 + }
+443
encoding/protobuf/textproto/decoder.go
··· 1 + // Copyright 2021 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 textproto 16 + 17 + import ( 18 + "fmt" 19 + "strings" 20 + 21 + "cuelang.org/go/cue" 22 + "cuelang.org/go/cue/ast" 23 + "cuelang.org/go/cue/errors" 24 + "cuelang.org/go/cue/literal" 25 + "cuelang.org/go/cue/token" 26 + "cuelang.org/go/encoding/protobuf/pbinternal" 27 + "cuelang.org/go/internal/core/adt" 28 + "cuelang.org/go/internal/value" 29 + 30 + pbast "github.com/protocolbuffers/txtpbfmt/ast" 31 + "github.com/protocolbuffers/txtpbfmt/parser" 32 + "github.com/protocolbuffers/txtpbfmt/unquote" 33 + ) 34 + 35 + // Option defines options for the decoder. 36 + // There are currently no options. 37 + type Option func(*options) 38 + 39 + type options struct { 40 + } 41 + 42 + // NewDecoder returns a new Decoder 43 + func NewDecoder(option ...Option) *Decoder { 44 + d := &Decoder{} 45 + _ = d.m // work around linter bug. 46 + return d 47 + } 48 + 49 + // A Decoder caches conversions of cue.Value between calls to its methods. 50 + type Decoder struct { 51 + m map[*adt.Vertex]*mapping 52 + } 53 + 54 + type decoder struct { 55 + *Decoder 56 + 57 + // Reset on each call 58 + errs errors.Error 59 + file *token.File 60 + } 61 + 62 + // Parse parses the given textproto bytes and converts them to a CUE expression, 63 + // using schema as the guideline for conversion using the following rules: 64 + // 65 + // - the @protobuf attribute is optional, but is necessary for: 66 + // - interpreting protobuf maps 67 + // - using a name different from the CUE name 68 + // - fields in the textproto that have no corresponding field in 69 + // schema are ignored 70 + // 71 + // NOTE: the filename is used for associating position information. However, 72 + // currently no position information is associated with the text proto because 73 + // the position information of github.com/protocolbuffers/txtpbfmt is too 74 + // unreliable to be useful. 75 + func (d *Decoder) Parse(schema cue.Value, filename string, b []byte) (ast.Expr, error) { 76 + dec := decoder{Decoder: d} 77 + 78 + // dec.errs = nil 79 + 80 + f := token.NewFile(filename, 0, len(b)) 81 + f.SetLinesForContent(b) 82 + dec.file = f 83 + 84 + cfg := parser.Config{} 85 + nodes, err := parser.ParseWithConfig(b, cfg) 86 + if err != nil { 87 + return nil, errors.Newf(token.NoPos, "textproto: %v", err) 88 + } 89 + 90 + m := dec.parseSchema(schema) 91 + if dec.errs != nil { 92 + return nil, dec.errs 93 + } 94 + 95 + n := dec.decodeMsg(m, nodes) 96 + if dec.errs != nil { 97 + return nil, dec.errs 98 + } 99 + 100 + return n, nil 101 + } 102 + 103 + // Don't expose until the protobuf APIs settle down. 104 + // func (d *decoder) Decode(schema cue.Value, textpbfmt) (cue.Value, error) { 105 + // } 106 + 107 + type mapping struct { 108 + children map[string]*fieldInfo 109 + } 110 + 111 + type fieldInfo struct { 112 + pbinternal.Info 113 + msg *mapping 114 + // keytype, for now 115 + } 116 + 117 + func (d *decoder) addErr(err error) { 118 + d.errs = errors.Append(d.errs, errors.Promote(err, "textproto")) 119 + } 120 + 121 + func (d *decoder) addErrf(pos pbast.Position, format string, args ...interface{}) { 122 + err := errors.Newf(d.protoPos(pos), "textproto: "+format, args...) 123 + d.errs = errors.Append(d.errs, err) 124 + } 125 + 126 + func (d *decoder) protoPos(p pbast.Position) token.Pos { 127 + return d.file.Pos(int(p.Byte), token.NoRelPos) 128 + } 129 + 130 + // parseSchema walks over a CUE "type", converts it to an internal data 131 + // structure that is used for parsing text proto, and writes it to 132 + // 133 + func (d *decoder) parseSchema(schema cue.Value) *mapping { 134 + _, v := value.ToInternal(schema) 135 + if v == nil { 136 + return nil 137 + } 138 + 139 + if d.m == nil { 140 + d.m = map[*adt.Vertex]*mapping{} 141 + } else if m := d.m[v]; m != nil { 142 + return m 143 + } 144 + 145 + m := &mapping{children: map[string]*fieldInfo{}} 146 + 147 + i, err := schema.Fields() 148 + if err != nil { 149 + d.addErr(err) 150 + return nil 151 + } 152 + 153 + for i.Next() { 154 + info, err := pbinternal.FromIter(i) 155 + if err != nil { 156 + d.addErr(err) 157 + continue 158 + } 159 + 160 + var msg *mapping 161 + 162 + switch info.CompositeType { 163 + case pbinternal.Normal: 164 + switch info.ValueType { 165 + case pbinternal.Message: 166 + msg = d.parseSchema(i.Value()) 167 + } 168 + 169 + case pbinternal.List, pbinternal.Map: 170 + e, _ := i.Value().Elem() 171 + if e.IncompleteKind() == cue.StructKind { 172 + msg = d.parseSchema(e) 173 + } 174 + } 175 + 176 + m.children[info.Name] = &fieldInfo{ 177 + Info: info, 178 + msg: msg, 179 + } 180 + } 181 + 182 + d.m[v] = m 183 + return m 184 + } 185 + 186 + func (d *decoder) decodeMsg(m *mapping, n []*pbast.Node) ast.Expr { 187 + st := &ast.StructLit{} 188 + 189 + var listMap map[string]*ast.ListLit 190 + 191 + for _, x := range n { 192 + if x.Values == nil && x.Children == nil { 193 + if cg := addComments(x.PreComments...); cg != nil { 194 + ast.SetRelPos(cg, token.NewSection) 195 + st.Elts = append(st.Elts, cg) 196 + continue 197 + } 198 + } 199 + if m == nil { 200 + continue 201 + } 202 + f, ok := m.children[x.Name] 203 + if !ok { 204 + continue // ignore unknown fields 205 + } 206 + 207 + var value ast.Expr 208 + 209 + switch f.CompositeType { 210 + default: 211 + value = d.decodeValue(f, x) 212 + 213 + case pbinternal.List: 214 + if listMap == nil { 215 + listMap = make(map[string]*ast.ListLit) 216 + } 217 + 218 + list := listMap[f.CUEName] 219 + if list == nil { 220 + list = &ast.ListLit{} 221 + listMap[f.CUEName] = list 222 + value = list 223 + } 224 + 225 + if len(x.Values) == 1 || f.ValueType == pbinternal.Message { 226 + v := d.decodeValue(f, x) 227 + if value == nil { 228 + if cg := addComments(x.PreComments...); cg != nil { 229 + cg.Doc = true 230 + ast.AddComment(v, cg) 231 + } 232 + } 233 + if cg := addComments(x.PostValuesComments...); cg != nil { 234 + cg.Position = 4 235 + ast.AddComment(v, cg) 236 + } 237 + list.Elts = append(list.Elts, v) 238 + break 239 + } 240 + 241 + var last ast.Expr 242 + // Handle [1, 2, 3] 243 + for _, v := range x.Values { 244 + if v.Value == "" { 245 + if cg := addComments(v.PreComments...); cg != nil { 246 + if last != nil { 247 + cg.Position = 4 248 + ast.AddComment(last, cg) 249 + } else { 250 + cg.Position = 1 251 + ast.AddComment(list, cg) 252 + } 253 + } 254 + continue 255 + } 256 + y := *x 257 + y.Values = []*pbast.Value{v} 258 + last = d.decodeValue(f, &y) 259 + list.Elts = append(list.Elts, last) 260 + } 261 + if cg := addComments(x.PostValuesComments...); cg != nil { 262 + if last != nil { 263 + cg.Position = 4 264 + ast.AddComment(last, cg) 265 + } else { 266 + cg.Position = 1 267 + ast.AddComment(list, cg) 268 + } 269 + } 270 + if cg := addComments(x.ClosingBraceComment); cg != nil { 271 + cg.Position = 4 272 + ast.AddComment(list, cg) 273 + } 274 + 275 + case pbinternal.Map: 276 + // mapValue: { 277 + // key: 123 278 + // value: "string" 279 + // } 280 + if k := len(x.Values); k > 0 { 281 + d.addErrf(x.Start, "values not allowed for Message type; found %d", k) 282 + } 283 + 284 + var ( 285 + key ast.Label 286 + val ast.Expr 287 + ) 288 + 289 + for _, c := range x.Children { 290 + if len(c.Values) != 1 { 291 + d.addErrf(x.Start, "expected 1 value, found %d", len(c.Values)) 292 + continue 293 + } 294 + s := c.Values[0].Value 295 + 296 + switch c.Name { 297 + case "key": 298 + if strings.HasPrefix(s, `"`) { 299 + key = &ast.BasicLit{Kind: token.STRING, Value: s} 300 + } else { 301 + key = ast.NewString(s) 302 + } 303 + 304 + case "value": 305 + val = d.decodeValue(f, c) 306 + 307 + if cg := addComments(x.ClosingBraceComment); cg != nil { 308 + cg.Line = true 309 + ast.AddComment(val, cg) 310 + } 311 + 312 + default: 313 + d.addErrf(c.Start, "unsupported key name %q in map", c.Name) 314 + continue 315 + } 316 + } 317 + 318 + if key != nil && val != nil { 319 + value = ast.NewStruct(key, val) 320 + } 321 + } 322 + 323 + if value != nil { 324 + var label ast.Label 325 + if s := f.CUEName; ast.IsValidIdent(s) { 326 + label = ast.NewIdent(s) 327 + } else { 328 + label = ast.NewString(s) 329 + 330 + } 331 + // TODO: convert line number information. However, position 332 + // information in textpbfmt packages is too wonky to be useful 333 + f := &ast.Field{ 334 + Label: label, 335 + Value: value, 336 + // Attrs: []*ast.Attribute{{Text: f.attr.}}, 337 + } 338 + if cg := addComments(x.PreComments...); cg != nil { 339 + cg.Doc = true 340 + ast.AddComment(f, cg) 341 + } 342 + st.Elts = append(st.Elts, f) 343 + } 344 + } 345 + 346 + return st 347 + } 348 + 349 + func addComments(lines ...string) (cg *ast.CommentGroup) { 350 + var a []*ast.Comment 351 + for _, c := range lines { 352 + if !strings.HasPrefix(c, "#") { 353 + continue 354 + } 355 + a = append(a, &ast.Comment{Text: "//" + c[1:]}) 356 + } 357 + if a != nil { 358 + cg = &ast.CommentGroup{List: a} 359 + } 360 + return cg 361 + } 362 + 363 + func (d *decoder) decodeValue(f *fieldInfo, n *pbast.Node) (x ast.Expr) { 364 + if f.ValueType == pbinternal.Message { 365 + if k := len(n.Values); k > 0 { 366 + d.addErrf(n.Start, "values not allowed for Message type; found %d", k) 367 + } 368 + x = d.decodeMsg(f.msg, n.Children) 369 + if cg := addComments(n.ClosingBraceComment); cg != nil { 370 + cg.Line = true 371 + cg.Position = 4 372 + ast.AddComment(x, cg) 373 + } 374 + return x 375 + } 376 + 377 + if len(n.Values) != 1 { 378 + d.addErrf(n.Start, "expected 1 value, found %d", len(n.Values)) 379 + return nil 380 + } 381 + v := n.Values[0] 382 + 383 + defer func() { 384 + if cg := addComments(v.PreComments...); cg != nil { 385 + cg.Doc = true 386 + ast.AddComment(x, cg) 387 + } 388 + if cg := addComments(v.InlineComment); cg != nil { 389 + cg.Line = true 390 + cg.Position = 2 391 + ast.AddComment(x, cg) 392 + } 393 + }() 394 + 395 + switch f.ValueType { 396 + case pbinternal.String, pbinternal.Bytes: 397 + s, err := unquote.Unquote(n) 398 + if err != nil { 399 + d.addErrf(n.Start, "invalid string or bytes: %v", err) 400 + } 401 + if f.ValueType == pbinternal.String { 402 + s = literal.String.Quote(s) 403 + } else { 404 + s = literal.Bytes.Quote(s) 405 + } 406 + return &ast.BasicLit{Kind: token.STRING, Value: s} 407 + 408 + case pbinternal.Bool: 409 + switch v.Value { 410 + case "true": 411 + return ast.NewBool(true) 412 + 413 + case "false": 414 + default: 415 + d.addErrf(n.Start, "invalid bool %s", v.Value) 416 + } 417 + return ast.NewBool(false) 418 + 419 + case pbinternal.Int, pbinternal.Float: 420 + s := v.Value 421 + switch s { 422 + case "inf", "nan": 423 + // TODO: include message. 424 + return &ast.BottomLit{} 425 + } 426 + 427 + var info literal.NumInfo 428 + if err := literal.ParseNum(s, &info); err != nil { 429 + var x ast.BasicLit 430 + if pbinternal.MatchBySymbol(f.Value, s, &x) { 431 + return &x 432 + } 433 + d.addErrf(n.Start, "invalid number %s", s) 434 + } 435 + if !info.IsInt() { 436 + return &ast.BasicLit{Kind: token.FLOAT, Value: s} 437 + } 438 + return &ast.BasicLit{Kind: token.INT, Value: info.String()} 439 + 440 + default: 441 + panic(fmt.Sprintf("unexpected type %v", f.ValueType)) 442 + } 443 + }
+80
encoding/protobuf/textproto/decoder_test.go
··· 1 + // Copyright 2021 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 textproto_test 16 + 17 + import ( 18 + "strings" 19 + "testing" 20 + 21 + "cuelang.org/go/cue" 22 + "cuelang.org/go/cue/ast/astutil" 23 + "cuelang.org/go/cue/errors" 24 + "cuelang.org/go/cue/format" 25 + "cuelang.org/go/encoding/protobuf/textproto" 26 + "cuelang.org/go/internal/cuetest" 27 + "cuelang.org/go/internal/cuetxtar" 28 + ) 29 + 30 + func TestParse(t *testing.T) { 31 + test := cuetxtar.TxTarTest{ 32 + Root: "./testdata/decoder", 33 + Name: "decode", 34 + Update: cuetest.UpdateGoldenFiles, 35 + } 36 + 37 + r := cue.Runtime{} 38 + 39 + d := textproto.NewDecoder() 40 + 41 + test.Run(t, func(t *cuetxtar.Test) { 42 + // TODO: use high-level API. 43 + 44 + var schema cue.Value 45 + var filename string 46 + var b []byte 47 + 48 + for _, f := range t.Archive.Files { 49 + switch { 50 + case strings.HasSuffix(f.Name, ".cue"): 51 + inst, err := r.Compile(f.Name, f.Data) 52 + if err != nil { 53 + t.WriteErrors(errors.Promote(err, "test")) 54 + return 55 + } 56 + schema = inst.Value() 57 + 58 + case strings.HasSuffix(f.Name, ".textproto"): 59 + filename = f.Name 60 + b = f.Data 61 + } 62 + } 63 + 64 + x, err := d.Parse(schema, filename, b) 65 + if err != nil { 66 + t.WriteErrors(errors.Promote(err, "test")) 67 + return 68 + } 69 + 70 + f, err := astutil.ToFile(x) 71 + if err != nil { 72 + t.WriteErrors(errors.Promote(err, "test")) 73 + } 74 + b, err = format.Node(f) 75 + if err != nil { 76 + t.WriteErrors(errors.Promote(err, "test")) 77 + } 78 + _, _ = t.Write(b) 79 + }) 80 + }
+27
encoding/protobuf/textproto/doc.go
··· 1 + // Copyright 2021 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 textproto converts text protobuffer files to and from CUE. 16 + // 17 + // Note that textproto is an unofficial standard and that there are no 18 + // specifications: the recommended packages are the de facto standard for the 19 + // relevant programming languages and the recommended implementations may vary 20 + // considerably between them. 21 + // 22 + // Also, the standard text proto parsing libraries are rather buggy. Please 23 + // verify that a parsing issues is not related these libraries before filing 24 + // bugs with CUE. 25 + // 26 + // API Status: DRAFT: API may change without notice. 27 + package textproto
+116
encoding/protobuf/textproto/testdata/decoder/comments.txtar
··· 1 + // TODO: there are many missing comments, but these really are consequences 2 + // of the buggy textpbfmt library. 3 + 4 + -- foo.cue -- 5 + a: string 6 + b: [...int] 7 + c: [...int32] 8 + m: [...#Msg] 9 + #Msg: { 10 + x: string 11 + y: string 12 + } 13 + 14 + -- input.textproto -- 15 + # file comment 16 + 17 + # doc comment a 18 + a: "dsfadsafsaf" # line comment 19 + 20 + # floating comment a-b 21 + 22 + # doc comment b 23 + b: [ 24 + # pre-elem comment 25 + 26 + # doc elem 0 27 + 123, # elem 0 line comment 28 + # trailing elem 0 29 + 30 + # inbetween comment 1 31 + 32 + # inbetween comment 2 33 + 34 + # doc elem 1 35 + 456 # elem 1 line comment 36 + # trailing elem 1 37 + 38 + # final floating 1 39 + 40 + # final floating 2 41 + ] 42 + # floating end 43 + 44 + c: 2342134 # line elem 0 45 + c: 2342135 # line elem 1 46 + # inbetween elems 47 + c: 2342136 # line elem 2 48 + # after list c 49 + 50 + # floating 51 + 52 + m { 53 + x: "sdfff" # inner line comment 54 + y: "q\"qq\\q\n" 55 + # after last value 56 + } # after elem line 57 + # after elem separate 58 + m { 59 + x: " sdfff2 \321\202\320\265\321\201\321\202 " 60 + y: "q\tqq<>q2&\001\377" 61 + } # after list line 62 + # after list 63 + 64 + # floating end 65 + 66 + -- out/decode -- 67 + // file comment 68 + 69 + // doc comment a 70 + a: "dsfadsafsaf" // line comment 71 + 72 + // floating comment a-b 73 + 74 + // doc comment b 75 + b: [ 76 + // pre-elem comment 77 + 123, // elem 0 line comment 78 + 79 + // trailing elem 0 80 + // inbetween comment 2 81 + 456, // elem 1 line comment 82 + 83 + // trailing elem 1 84 + 85 + // final floating 2 86 + ] 87 + 88 + // floating end 89 + 90 + c: [2342134, // line elem 0 91 + 2342135, // line elem 1 92 + // inbetween elems 93 + 2342136, // line elem 2 94 + ] 95 + 96 + // after list c 97 + 98 + // floating 99 + 100 + m: [{ 101 + x: "sdfff" // inner line comment 102 + y: "q\"qq\\q\n" 103 + 104 + // after last value 105 + 106 + }, // after elem line 107 + // after elem separate 108 + { 109 + x: " sdfff2 тест " 110 + y: "q\tqq<>q2&\u0001�" 111 + }, // after list line 112 + ] 113 + 114 + // after list 115 + 116 + // floating end
+23
encoding/protobuf/textproto/testdata/decoder/enums.txtar
··· 1 + -- foo.cue -- 2 + #MyEnum: 3 + #Val1 | 4 + #Val2 | 5 + #Val3 6 + 7 + #Val1: 1 8 + #Val2: 2 9 + #Val3: 3 10 + 11 + a0: #MyEnum 12 + a1: [...#MyEnum] 13 + 14 + -- input.textproto -- 15 + a0: Val1 16 + a1: Val1 17 + a1: Val2 18 + a1: Val3 19 + a1: 2 20 + 21 + -- out/decode -- 22 + a0: 1 23 + a1: [1, 2, 3, 2]
+12
encoding/protobuf/textproto/testdata/decoder/errors.txtar
··· 1 + # The error in input.textproto (wrong comment style) is going undetected. 2 + # This is a protobuf bug. Can't do much about it. 3 + -- errors.cue -- 4 + a: int 5 + 6 + -- input.textproto -- 7 + 8 + // Silent nights 9 + a: 1 10 + 11 + -- out/decode -- 12 +
+47
encoding/protobuf/textproto/testdata/decoder/list.txtar
··· 1 + // test of non-standard list 2 + 3 + // TODO: there are many missing comments, but these really are consequences 4 + // of the buggy textpbfmt library. 5 + 6 + -- list.cue -- 7 + empty1: [...int] 8 + empty2: [...int] 9 + 10 + int1: [...int] 11 + int2: [...int] 12 + int3: [...int] 13 + 14 + string1: [...string] 15 + 16 + float1: [...number] 17 + 18 + 19 + -- input.textproto -- 20 + empty1: [] 21 + empty2: [ # foo 22 + ] 23 + 24 + int1: [1, 2] 25 + int2: [1 2] # omitting commas okay 26 + int3: [ 27 + 1 # omitting comma okay 28 + 2 29 + ] 30 + 31 + string1: [ 32 + "a", # omitting comma NOT supported 33 + "b" 34 + ] 35 + 36 + float1: [ 1e+2 1. 0] 37 + -- out/decode -- 38 + empty1: [] 39 + empty2: [ // foo 40 + ] 41 + int1: [1, 2] 42 + int2: [1, 2] // omitting commas okay 43 + int3: [1, // omitting comma okay 44 + 2] 45 + string1: ["a", // omitting comma NOT supported 46 + "b"] 47 + float1: [1e+2, 1.0, 0]
+51
encoding/protobuf/textproto/testdata/decoder/map.txtar
··· 1 + -- map.cue -- 2 + map: {[string]: int} @protobuf(1,map[string]int) 3 + 4 + 5 + implicit: [string]: string 6 + 7 + intMap: {[string]: int} @protobuf(1,map[int]int) 8 + 9 + -- input.textproto -- 10 + map: { 11 + key: "foo" 12 + value: 2 13 + } 14 + map: { 15 + key: "bar" 16 + value: 3 17 + } 18 + 19 + implicit: { 20 + key: "foo" 21 + value: 2 22 + } 23 + implicit: { 24 + key: "bar" 25 + value: 3 26 + } 27 + 28 + intMap: { 29 + key: 100 30 + value: 2 31 + } 32 + intMap: { 33 + key: 102 34 + value: 3 35 + } 36 + 37 + -- out/decode -- 38 + map: { 39 + "foo": 2 40 + } 41 + map: { 42 + "bar": 3 43 + } 44 + implicit: {} 45 + implicit: {} 46 + intMap: { 47 + "100": 2 48 + } 49 + intMap: { 50 + "102": 3 51 + }
+19
encoding/protobuf/textproto/testdata/decoder/scalar.txtar
··· 1 + -- map.cue -- 2 + inf: number 3 + nan: number 4 + 5 + t: bool 6 + f: bool 7 + 8 + 9 + -- input.textproto -- 10 + inf: inf 11 + nan: nan 12 + t: true 13 + f: false 14 + 15 + -- out/decode -- 16 + inf: _|_ 17 + nan: _|_ 18 + t: true 19 + f: false
+63
encoding/protobuf/textproto/testdata/decoder/simple.txtar
··· 1 + // From: https://stackoverflow.com/questions/18873924/what-does-the-protobuf-text-format-look-like 2 + -- foo.cue -- 3 + #MyEnum: "Default" | "Variant1" | "Variant100" 4 + 5 + f1: string 6 + f2: int64 7 + fa: [...uint64] 8 + fb: [...int32] 9 + fc: [...number] 10 + pairs: [...#Pair] 11 + bbbb: bytes // optional 12 + 13 + // extensions 100 to max; 14 + 15 + #Pair: { 16 + key: string 17 + value: string 18 + } 19 + 20 + -- input.textproto -- 21 + f1: "dsfadsafsaf" 22 + f2: 234 # value comment 23 + 24 + fa: 2342134 25 + fa: 2342135 26 + fa: 2342136 27 + # Mix of list and single elements. 28 + fb: [ -2342134, -2342135, -2342136 ] 29 + fb: -1000 30 + 31 + fc: 4 32 + fc: 7 33 + fc: -12 34 + fc: 4 35 + fc: 7 36 + fc: -3 37 + fc: 4 38 + fc: 7 39 + fc: 0 40 + pairs { 41 + key: "sdfff" 42 + value: "q\"qq\\q\n" 43 + } 44 + pairs { 45 + key: " sdfff2 \321\202\320\265\321\201\321\202 " 46 + value: "q\tqq<>q2&\001\377" 47 + } 48 + bbbb: "\000\001\002\377\376\375" 49 + -- out/decode -- 50 + f1: "dsfadsafsaf" 51 + f2: 234 // value comment 52 + fa: [2342134, 2342135, 2342136] 53 + // Mix of list and single elements. 54 + fb: [-2342134, -2342135, -2342136, -1000] 55 + fc: [4, 7, -12, 4, 7, -3, 4, 7, 0] 56 + pairs: [{ 57 + key: "sdfff" 58 + value: "q\"qq\\q\n" 59 + }, { 60 + key: " sdfff2 тест " 61 + value: "q\tqq<>q2&\u0001�" 62 + }] 63 + bbbb: '\x00\x01\x02\xff\xfe\xfd'
+1
go.mod
··· 10 10 github.com/lib/pq v1.0.0 // indirect 11 11 github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de 12 12 github.com/pkg/errors v0.8.1 // indirect 13 + github.com/protocolbuffers/txtpbfmt v0.0.0-20201118171849-f6a6b3f636fc 13 14 github.com/rogpeppe/go-internal v1.8.0 14 15 github.com/spf13/cobra v1.0.0 15 16 github.com/spf13/pflag v1.0.3
+3
go.sum
··· 35 35 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 36 36 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 37 37 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 38 + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 38 39 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 39 40 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 40 41 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= ··· 91 92 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 92 93 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 93 94 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 95 + github.com/protocolbuffers/txtpbfmt v0.0.0-20201118171849-f6a6b3f636fc h1:gSVONBi2HWMFXCa9jFdYvYk7IwW/mTLxWOF7rXS4LO0= 96 + github.com/protocolbuffers/txtpbfmt v0.0.0-20201118171849-f6a6b3f636fc/go.mod h1:KbKfKPy2I6ecOIGA9apfheFv14+P3RSmmQvshofQyMY= 94 97 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 95 98 github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= 96 99 github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
+4 -4
internal/attrs_test.go
··· 48 48 in: `foo,bar,baz`, 49 49 out: "[{foo 0} {bar 0} {baz 0}]", 50 50 }, { 51 - in: `1,"map<int,string>"`, 52 - out: "[{1 0} {map<int,string> 0}]", 51 + in: `1,map[int]string`, 52 + out: "[{1 0} {map[int]string 0}]", 53 53 }, { 54 - in: `1, "map<int,string>"`, 55 - out: "[{1 0} {map<int,string> 0}]", 54 + in: `1,map[int]string`, 55 + out: "[{1 0} {map[int]string 0}]", 56 56 }, { 57 57 in: `bar=str`, 58 58 out: "[{bar=str 3}]",