podman

Форк
0
1018 строк · 25.2 Кб
1
// Protocol Buffers for Go with Gadgets
2
//
3
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
4
// http://github.com/gogo/protobuf
5
//
6
// Go support for Protocol Buffers - Google's data interchange format
7
//
8
// Copyright 2010 The Go Authors.  All rights reserved.
9
// https://github.com/golang/protobuf
10
//
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are
13
// met:
14
//
15
//     * Redistributions of source code must retain the above copyright
16
// notice, this list of conditions and the following disclaimer.
17
//     * Redistributions in binary form must reproduce the above
18
// copyright notice, this list of conditions and the following disclaimer
19
// in the documentation and/or other materials provided with the
20
// distribution.
21
//     * Neither the name of Google Inc. nor the names of its
22
// contributors may be used to endorse or promote products derived from
23
// this software without specific prior written permission.
24
//
25
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36

37
package proto
38

39
// Functions for parsing the Text protocol buffer format.
40
// TODO: message sets.
41

42
import (
43
	"encoding"
44
	"errors"
45
	"fmt"
46
	"reflect"
47
	"strconv"
48
	"strings"
49
	"time"
50
	"unicode/utf8"
51
)
52

53
// Error string emitted when deserializing Any and fields are already set
54
const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
55

56
type ParseError struct {
57
	Message string
58
	Line    int // 1-based line number
59
	Offset  int // 0-based byte offset from start of input
60
}
61

62
func (p *ParseError) Error() string {
63
	if p.Line == 1 {
64
		// show offset only for first line
65
		return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
66
	}
67
	return fmt.Sprintf("line %d: %v", p.Line, p.Message)
68
}
69

70
type token struct {
71
	value    string
72
	err      *ParseError
73
	line     int    // line number
74
	offset   int    // byte number from start of input, not start of line
75
	unquoted string // the unquoted version of value, if it was a quoted string
76
}
77

78
func (t *token) String() string {
79
	if t.err == nil {
80
		return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset)
81
	}
82
	return fmt.Sprintf("parse error: %v", t.err)
83
}
84

85
type textParser struct {
86
	s            string // remaining input
87
	done         bool   // whether the parsing is finished (success or error)
88
	backed       bool   // whether back() was called
89
	offset, line int
90
	cur          token
91
}
92

93
func newTextParser(s string) *textParser {
94
	p := new(textParser)
95
	p.s = s
96
	p.line = 1
97
	p.cur.line = 1
98
	return p
99
}
100

101
func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
102
	pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
103
	p.cur.err = pe
104
	p.done = true
105
	return pe
106
}
107

108
// Numbers and identifiers are matched by [-+._A-Za-z0-9]
109
func isIdentOrNumberChar(c byte) bool {
110
	switch {
111
	case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
112
		return true
113
	case '0' <= c && c <= '9':
114
		return true
115
	}
116
	switch c {
117
	case '-', '+', '.', '_':
118
		return true
119
	}
120
	return false
121
}
122

123
func isWhitespace(c byte) bool {
124
	switch c {
125
	case ' ', '\t', '\n', '\r':
126
		return true
127
	}
128
	return false
129
}
130

131
func isQuote(c byte) bool {
132
	switch c {
133
	case '"', '\'':
134
		return true
135
	}
136
	return false
137
}
138

139
func (p *textParser) skipWhitespace() {
140
	i := 0
141
	for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
142
		if p.s[i] == '#' {
143
			// comment; skip to end of line or input
144
			for i < len(p.s) && p.s[i] != '\n' {
145
				i++
146
			}
147
			if i == len(p.s) {
148
				break
149
			}
150
		}
151
		if p.s[i] == '\n' {
152
			p.line++
153
		}
154
		i++
155
	}
156
	p.offset += i
157
	p.s = p.s[i:len(p.s)]
158
	if len(p.s) == 0 {
159
		p.done = true
160
	}
161
}
162

163
func (p *textParser) advance() {
164
	// Skip whitespace
165
	p.skipWhitespace()
166
	if p.done {
167
		return
168
	}
169

170
	// Start of non-whitespace
171
	p.cur.err = nil
172
	p.cur.offset, p.cur.line = p.offset, p.line
173
	p.cur.unquoted = ""
174
	switch p.s[0] {
175
	case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
176
		// Single symbol
177
		p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
178
	case '"', '\'':
179
		// Quoted string
180
		i := 1
181
		for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
182
			if p.s[i] == '\\' && i+1 < len(p.s) {
183
				// skip escaped char
184
				i++
185
			}
186
			i++
187
		}
188
		if i >= len(p.s) || p.s[i] != p.s[0] {
189
			p.errorf("unmatched quote")
190
			return
191
		}
192
		unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
193
		if err != nil {
194
			p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
195
			return
196
		}
197
		p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
198
		p.cur.unquoted = unq
199
	default:
200
		i := 0
201
		for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
202
			i++
203
		}
204
		if i == 0 {
205
			p.errorf("unexpected byte %#x", p.s[0])
206
			return
207
		}
208
		p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
209
	}
210
	p.offset += len(p.cur.value)
211
}
212

213
var (
214
	errBadUTF8 = errors.New("proto: bad UTF-8")
215
)
216

217
func unquoteC(s string, quote rune) (string, error) {
218
	// This is based on C++'s tokenizer.cc.
219
	// Despite its name, this is *not* parsing C syntax.
220
	// For instance, "\0" is an invalid quoted string.
221

222
	// Avoid allocation in trivial cases.
223
	simple := true
224
	for _, r := range s {
225
		if r == '\\' || r == quote {
226
			simple = false
227
			break
228
		}
229
	}
230
	if simple {
231
		return s, nil
232
	}
233

234
	buf := make([]byte, 0, 3*len(s)/2)
235
	for len(s) > 0 {
236
		r, n := utf8.DecodeRuneInString(s)
237
		if r == utf8.RuneError && n == 1 {
238
			return "", errBadUTF8
239
		}
240
		s = s[n:]
241
		if r != '\\' {
242
			if r < utf8.RuneSelf {
243
				buf = append(buf, byte(r))
244
			} else {
245
				buf = append(buf, string(r)...)
246
			}
247
			continue
248
		}
249

250
		ch, tail, err := unescape(s)
251
		if err != nil {
252
			return "", err
253
		}
254
		buf = append(buf, ch...)
255
		s = tail
256
	}
257
	return string(buf), nil
258
}
259

260
func unescape(s string) (ch string, tail string, err error) {
261
	r, n := utf8.DecodeRuneInString(s)
262
	if r == utf8.RuneError && n == 1 {
263
		return "", "", errBadUTF8
264
	}
265
	s = s[n:]
266
	switch r {
267
	case 'a':
268
		return "\a", s, nil
269
	case 'b':
270
		return "\b", s, nil
271
	case 'f':
272
		return "\f", s, nil
273
	case 'n':
274
		return "\n", s, nil
275
	case 'r':
276
		return "\r", s, nil
277
	case 't':
278
		return "\t", s, nil
279
	case 'v':
280
		return "\v", s, nil
281
	case '?':
282
		return "?", s, nil // trigraph workaround
283
	case '\'', '"', '\\':
284
		return string(r), s, nil
285
	case '0', '1', '2', '3', '4', '5', '6', '7':
286
		if len(s) < 2 {
287
			return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
288
		}
289
		ss := string(r) + s[:2]
290
		s = s[2:]
291
		i, err := strconv.ParseUint(ss, 8, 8)
292
		if err != nil {
293
			return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss)
294
		}
295
		return string([]byte{byte(i)}), s, nil
296
	case 'x', 'X', 'u', 'U':
297
		var n int
298
		switch r {
299
		case 'x', 'X':
300
			n = 2
301
		case 'u':
302
			n = 4
303
		case 'U':
304
			n = 8
305
		}
306
		if len(s) < n {
307
			return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n)
308
		}
309
		ss := s[:n]
310
		s = s[n:]
311
		i, err := strconv.ParseUint(ss, 16, 64)
312
		if err != nil {
313
			return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss)
314
		}
315
		if r == 'x' || r == 'X' {
316
			return string([]byte{byte(i)}), s, nil
317
		}
318
		if i > utf8.MaxRune {
319
			return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
320
		}
321
		return string(rune(i)), s, nil
322
	}
323
	return "", "", fmt.Errorf(`unknown escape \%c`, r)
324
}
325

326
// Back off the parser by one token. Can only be done between calls to next().
327
// It makes the next advance() a no-op.
328
func (p *textParser) back() { p.backed = true }
329

330
// Advances the parser and returns the new current token.
331
func (p *textParser) next() *token {
332
	if p.backed || p.done {
333
		p.backed = false
334
		return &p.cur
335
	}
336
	p.advance()
337
	if p.done {
338
		p.cur.value = ""
339
	} else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {
340
		// Look for multiple quoted strings separated by whitespace,
341
		// and concatenate them.
342
		cat := p.cur
343
		for {
344
			p.skipWhitespace()
345
			if p.done || !isQuote(p.s[0]) {
346
				break
347
			}
348
			p.advance()
349
			if p.cur.err != nil {
350
				return &p.cur
351
			}
352
			cat.value += " " + p.cur.value
353
			cat.unquoted += p.cur.unquoted
354
		}
355
		p.done = false // parser may have seen EOF, but we want to return cat
356
		p.cur = cat
357
	}
358
	return &p.cur
359
}
360

361
func (p *textParser) consumeToken(s string) error {
362
	tok := p.next()
363
	if tok.err != nil {
364
		return tok.err
365
	}
366
	if tok.value != s {
367
		p.back()
368
		return p.errorf("expected %q, found %q", s, tok.value)
369
	}
370
	return nil
371
}
372

373
// Return a RequiredNotSetError indicating which required field was not set.
374
func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
375
	st := sv.Type()
376
	sprops := GetProperties(st)
377
	for i := 0; i < st.NumField(); i++ {
378
		if !isNil(sv.Field(i)) {
379
			continue
380
		}
381

382
		props := sprops.Prop[i]
383
		if props.Required {
384
			return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
385
		}
386
	}
387
	return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", st)} // should not happen
388
}
389

390
// Returns the index in the struct for the named field, as well as the parsed tag properties.
391
func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
392
	i, ok := sprops.decoderOrigNames[name]
393
	if ok {
394
		return i, sprops.Prop[i], true
395
	}
396
	return -1, nil, false
397
}
398

399
// Consume a ':' from the input stream (if the next token is a colon),
400
// returning an error if a colon is needed but not present.
401
func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
402
	tok := p.next()
403
	if tok.err != nil {
404
		return tok.err
405
	}
406
	if tok.value != ":" {
407
		// Colon is optional when the field is a group or message.
408
		needColon := true
409
		switch props.Wire {
410
		case "group":
411
			needColon = false
412
		case "bytes":
413
			// A "bytes" field is either a message, a string, or a repeated field;
414
			// those three become *T, *string and []T respectively, so we can check for
415
			// this field being a pointer to a non-string.
416
			if typ.Kind() == reflect.Ptr {
417
				// *T or *string
418
				if typ.Elem().Kind() == reflect.String {
419
					break
420
				}
421
			} else if typ.Kind() == reflect.Slice {
422
				// []T or []*T
423
				if typ.Elem().Kind() != reflect.Ptr {
424
					break
425
				}
426
			} else if typ.Kind() == reflect.String {
427
				// The proto3 exception is for a string field,
428
				// which requires a colon.
429
				break
430
			}
431
			needColon = false
432
		}
433
		if needColon {
434
			return p.errorf("expected ':', found %q", tok.value)
435
		}
436
		p.back()
437
	}
438
	return nil
439
}
440

441
func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
442
	st := sv.Type()
443
	sprops := GetProperties(st)
444
	reqCount := sprops.reqCount
445
	var reqFieldErr error
446
	fieldSet := make(map[string]bool)
447
	// A struct is a sequence of "name: value", terminated by one of
448
	// '>' or '}', or the end of the input.  A name may also be
449
	// "[extension]" or "[type/url]".
450
	//
451
	// The whole struct can also be an expanded Any message, like:
452
	// [type/url] < ... struct contents ... >
453
	for {
454
		tok := p.next()
455
		if tok.err != nil {
456
			return tok.err
457
		}
458
		if tok.value == terminator {
459
			break
460
		}
461
		if tok.value == "[" {
462
			// Looks like an extension or an Any.
463
			//
464
			// TODO: Check whether we need to handle
465
			// namespace rooted names (e.g. ".something.Foo").
466
			extName, err := p.consumeExtName()
467
			if err != nil {
468
				return err
469
			}
470

471
			if s := strings.LastIndex(extName, "/"); s >= 0 {
472
				// If it contains a slash, it's an Any type URL.
473
				messageName := extName[s+1:]
474
				mt := MessageType(messageName)
475
				if mt == nil {
476
					return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
477
				}
478
				tok = p.next()
479
				if tok.err != nil {
480
					return tok.err
481
				}
482
				// consume an optional colon
483
				if tok.value == ":" {
484
					tok = p.next()
485
					if tok.err != nil {
486
						return tok.err
487
					}
488
				}
489
				var terminator string
490
				switch tok.value {
491
				case "<":
492
					terminator = ">"
493
				case "{":
494
					terminator = "}"
495
				default:
496
					return p.errorf("expected '{' or '<', found %q", tok.value)
497
				}
498
				v := reflect.New(mt.Elem())
499
				if pe := p.readStruct(v.Elem(), terminator); pe != nil {
500
					return pe
501
				}
502
				b, err := Marshal(v.Interface().(Message))
503
				if err != nil {
504
					return p.errorf("failed to marshal message of type %q: %v", messageName, err)
505
				}
506
				if fieldSet["type_url"] {
507
					return p.errorf(anyRepeatedlyUnpacked, "type_url")
508
				}
509
				if fieldSet["value"] {
510
					return p.errorf(anyRepeatedlyUnpacked, "value")
511
				}
512
				sv.FieldByName("TypeUrl").SetString(extName)
513
				sv.FieldByName("Value").SetBytes(b)
514
				fieldSet["type_url"] = true
515
				fieldSet["value"] = true
516
				continue
517
			}
518

519
			var desc *ExtensionDesc
520
			// This could be faster, but it's functional.
521
			// TODO: Do something smarter than a linear scan.
522
			for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
523
				if d.Name == extName {
524
					desc = d
525
					break
526
				}
527
			}
528
			if desc == nil {
529
				return p.errorf("unrecognized extension %q", extName)
530
			}
531

532
			props := &Properties{}
533
			props.Parse(desc.Tag)
534

535
			typ := reflect.TypeOf(desc.ExtensionType)
536
			if err := p.checkForColon(props, typ); err != nil {
537
				return err
538
			}
539

540
			rep := desc.repeated()
541

542
			// Read the extension structure, and set it in
543
			// the value we're constructing.
544
			var ext reflect.Value
545
			if !rep {
546
				ext = reflect.New(typ).Elem()
547
			} else {
548
				ext = reflect.New(typ.Elem()).Elem()
549
			}
550
			if err := p.readAny(ext, props); err != nil {
551
				if _, ok := err.(*RequiredNotSetError); !ok {
552
					return err
553
				}
554
				reqFieldErr = err
555
			}
556
			ep := sv.Addr().Interface().(Message)
557
			if !rep {
558
				SetExtension(ep, desc, ext.Interface())
559
			} else {
560
				old, err := GetExtension(ep, desc)
561
				var sl reflect.Value
562
				if err == nil {
563
					sl = reflect.ValueOf(old) // existing slice
564
				} else {
565
					sl = reflect.MakeSlice(typ, 0, 1)
566
				}
567
				sl = reflect.Append(sl, ext)
568
				SetExtension(ep, desc, sl.Interface())
569
			}
570
			if err := p.consumeOptionalSeparator(); err != nil {
571
				return err
572
			}
573
			continue
574
		}
575

576
		// This is a normal, non-extension field.
577
		name := tok.value
578
		var dst reflect.Value
579
		fi, props, ok := structFieldByName(sprops, name)
580
		if ok {
581
			dst = sv.Field(fi)
582
		} else if oop, ok := sprops.OneofTypes[name]; ok {
583
			// It is a oneof.
584
			props = oop.Prop
585
			nv := reflect.New(oop.Type.Elem())
586
			dst = nv.Elem().Field(0)
587
			field := sv.Field(oop.Field)
588
			if !field.IsNil() {
589
				return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
590
			}
591
			field.Set(nv)
592
		}
593
		if !dst.IsValid() {
594
			return p.errorf("unknown field name %q in %v", name, st)
595
		}
596

597
		if dst.Kind() == reflect.Map {
598
			// Consume any colon.
599
			if err := p.checkForColon(props, dst.Type()); err != nil {
600
				return err
601
			}
602

603
			// Construct the map if it doesn't already exist.
604
			if dst.IsNil() {
605
				dst.Set(reflect.MakeMap(dst.Type()))
606
			}
607
			key := reflect.New(dst.Type().Key()).Elem()
608
			val := reflect.New(dst.Type().Elem()).Elem()
609

610
			// The map entry should be this sequence of tokens:
611
			//	< key : KEY value : VALUE >
612
			// However, implementations may omit key or value, and technically
613
			// we should support them in any order.  See b/28924776 for a time
614
			// this went wrong.
615

616
			tok := p.next()
617
			var terminator string
618
			switch tok.value {
619
			case "<":
620
				terminator = ">"
621
			case "{":
622
				terminator = "}"
623
			default:
624
				return p.errorf("expected '{' or '<', found %q", tok.value)
625
			}
626
			for {
627
				tok := p.next()
628
				if tok.err != nil {
629
					return tok.err
630
				}
631
				if tok.value == terminator {
632
					break
633
				}
634
				switch tok.value {
635
				case "key":
636
					if err := p.consumeToken(":"); err != nil {
637
						return err
638
					}
639
					if err := p.readAny(key, props.MapKeyProp); err != nil {
640
						return err
641
					}
642
					if err := p.consumeOptionalSeparator(); err != nil {
643
						return err
644
					}
645
				case "value":
646
					if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil {
647
						return err
648
					}
649
					if err := p.readAny(val, props.MapValProp); err != nil {
650
						return err
651
					}
652
					if err := p.consumeOptionalSeparator(); err != nil {
653
						return err
654
					}
655
				default:
656
					p.back()
657
					return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
658
				}
659
			}
660

661
			dst.SetMapIndex(key, val)
662
			continue
663
		}
664

665
		// Check that it's not already set if it's not a repeated field.
666
		if !props.Repeated && fieldSet[name] {
667
			return p.errorf("non-repeated field %q was repeated", name)
668
		}
669

670
		if err := p.checkForColon(props, dst.Type()); err != nil {
671
			return err
672
		}
673

674
		// Parse into the field.
675
		fieldSet[name] = true
676
		if err := p.readAny(dst, props); err != nil {
677
			if _, ok := err.(*RequiredNotSetError); !ok {
678
				return err
679
			}
680
			reqFieldErr = err
681
		}
682
		if props.Required {
683
			reqCount--
684
		}
685

686
		if err := p.consumeOptionalSeparator(); err != nil {
687
			return err
688
		}
689

690
	}
691

692
	if reqCount > 0 {
693
		return p.missingRequiredFieldError(sv)
694
	}
695
	return reqFieldErr
696
}
697

698
// consumeExtName consumes extension name or expanded Any type URL and the
699
// following ']'. It returns the name or URL consumed.
700
func (p *textParser) consumeExtName() (string, error) {
701
	tok := p.next()
702
	if tok.err != nil {
703
		return "", tok.err
704
	}
705

706
	// If extension name or type url is quoted, it's a single token.
707
	if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
708
		name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
709
		if err != nil {
710
			return "", err
711
		}
712
		return name, p.consumeToken("]")
713
	}
714

715
	// Consume everything up to "]"
716
	var parts []string
717
	for tok.value != "]" {
718
		parts = append(parts, tok.value)
719
		tok = p.next()
720
		if tok.err != nil {
721
			return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
722
		}
723
		if p.done && tok.value != "]" {
724
			return "", p.errorf("unclosed type_url or extension name")
725
		}
726
	}
727
	return strings.Join(parts, ""), nil
728
}
729

730
// consumeOptionalSeparator consumes an optional semicolon or comma.
731
// It is used in readStruct to provide backward compatibility.
732
func (p *textParser) consumeOptionalSeparator() error {
733
	tok := p.next()
734
	if tok.err != nil {
735
		return tok.err
736
	}
737
	if tok.value != ";" && tok.value != "," {
738
		p.back()
739
	}
740
	return nil
741
}
742

743
func (p *textParser) readAny(v reflect.Value, props *Properties) error {
744
	tok := p.next()
745
	if tok.err != nil {
746
		return tok.err
747
	}
748
	if tok.value == "" {
749
		return p.errorf("unexpected EOF")
750
	}
751
	if len(props.CustomType) > 0 {
752
		if props.Repeated {
753
			t := reflect.TypeOf(v.Interface())
754
			if t.Kind() == reflect.Slice {
755
				tc := reflect.TypeOf(new(Marshaler))
756
				ok := t.Elem().Implements(tc.Elem())
757
				if ok {
758
					fv := v
759
					flen := fv.Len()
760
					if flen == fv.Cap() {
761
						nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1)
762
						reflect.Copy(nav, fv)
763
						fv.Set(nav)
764
					}
765
					fv.SetLen(flen + 1)
766

767
					// Read one.
768
					p.back()
769
					return p.readAny(fv.Index(flen), props)
770
				}
771
			}
772
		}
773
		if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {
774
			custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler)
775
			err := custom.Unmarshal([]byte(tok.unquoted))
776
			if err != nil {
777
				return p.errorf("%v %v: %v", err, v.Type(), tok.value)
778
			}
779
			v.Set(reflect.ValueOf(custom))
780
		} else {
781
			custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler)
782
			err := custom.Unmarshal([]byte(tok.unquoted))
783
			if err != nil {
784
				return p.errorf("%v %v: %v", err, v.Type(), tok.value)
785
			}
786
			v.Set(reflect.Indirect(reflect.ValueOf(custom)))
787
		}
788
		return nil
789
	}
790
	if props.StdTime {
791
		fv := v
792
		p.back()
793
		props.StdTime = false
794
		tproto := &timestamp{}
795
		err := p.readAny(reflect.ValueOf(tproto).Elem(), props)
796
		props.StdTime = true
797
		if err != nil {
798
			return err
799
		}
800
		tim, err := timestampFromProto(tproto)
801
		if err != nil {
802
			return err
803
		}
804
		if props.Repeated {
805
			t := reflect.TypeOf(v.Interface())
806
			if t.Kind() == reflect.Slice {
807
				if t.Elem().Kind() == reflect.Ptr {
808
					ts := fv.Interface().([]*time.Time)
809
					ts = append(ts, &tim)
810
					fv.Set(reflect.ValueOf(ts))
811
					return nil
812
				} else {
813
					ts := fv.Interface().([]time.Time)
814
					ts = append(ts, tim)
815
					fv.Set(reflect.ValueOf(ts))
816
					return nil
817
				}
818
			}
819
		}
820
		if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {
821
			v.Set(reflect.ValueOf(&tim))
822
		} else {
823
			v.Set(reflect.Indirect(reflect.ValueOf(&tim)))
824
		}
825
		return nil
826
	}
827
	if props.StdDuration {
828
		fv := v
829
		p.back()
830
		props.StdDuration = false
831
		dproto := &duration{}
832
		err := p.readAny(reflect.ValueOf(dproto).Elem(), props)
833
		props.StdDuration = true
834
		if err != nil {
835
			return err
836
		}
837
		dur, err := durationFromProto(dproto)
838
		if err != nil {
839
			return err
840
		}
841
		if props.Repeated {
842
			t := reflect.TypeOf(v.Interface())
843
			if t.Kind() == reflect.Slice {
844
				if t.Elem().Kind() == reflect.Ptr {
845
					ds := fv.Interface().([]*time.Duration)
846
					ds = append(ds, &dur)
847
					fv.Set(reflect.ValueOf(ds))
848
					return nil
849
				} else {
850
					ds := fv.Interface().([]time.Duration)
851
					ds = append(ds, dur)
852
					fv.Set(reflect.ValueOf(ds))
853
					return nil
854
				}
855
			}
856
		}
857
		if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {
858
			v.Set(reflect.ValueOf(&dur))
859
		} else {
860
			v.Set(reflect.Indirect(reflect.ValueOf(&dur)))
861
		}
862
		return nil
863
	}
864
	switch fv := v; fv.Kind() {
865
	case reflect.Slice:
866
		at := v.Type()
867
		if at.Elem().Kind() == reflect.Uint8 {
868
			// Special case for []byte
869
			if tok.value[0] != '"' && tok.value[0] != '\'' {
870
				// Deliberately written out here, as the error after
871
				// this switch statement would write "invalid []byte: ...",
872
				// which is not as user-friendly.
873
				return p.errorf("invalid string: %v", tok.value)
874
			}
875
			bytes := []byte(tok.unquoted)
876
			fv.Set(reflect.ValueOf(bytes))
877
			return nil
878
		}
879
		// Repeated field.
880
		if tok.value == "[" {
881
			// Repeated field with list notation, like [1,2,3].
882
			for {
883
				fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
884
				err := p.readAny(fv.Index(fv.Len()-1), props)
885
				if err != nil {
886
					return err
887
				}
888
				ntok := p.next()
889
				if ntok.err != nil {
890
					return ntok.err
891
				}
892
				if ntok.value == "]" {
893
					break
894
				}
895
				if ntok.value != "," {
896
					return p.errorf("Expected ']' or ',' found %q", ntok.value)
897
				}
898
			}
899
			return nil
900
		}
901
		// One value of the repeated field.
902
		p.back()
903
		fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
904
		return p.readAny(fv.Index(fv.Len()-1), props)
905
	case reflect.Bool:
906
		// true/1/t/True or false/f/0/False.
907
		switch tok.value {
908
		case "true", "1", "t", "True":
909
			fv.SetBool(true)
910
			return nil
911
		case "false", "0", "f", "False":
912
			fv.SetBool(false)
913
			return nil
914
		}
915
	case reflect.Float32, reflect.Float64:
916
		v := tok.value
917
		// Ignore 'f' for compatibility with output generated by C++, but don't
918
		// remove 'f' when the value is "-inf" or "inf".
919
		if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
920
			v = v[:len(v)-1]
921
		}
922
		if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
923
			fv.SetFloat(f)
924
			return nil
925
		}
926
	case reflect.Int8:
927
		if x, err := strconv.ParseInt(tok.value, 0, 8); err == nil {
928
			fv.SetInt(x)
929
			return nil
930
		}
931
	case reflect.Int16:
932
		if x, err := strconv.ParseInt(tok.value, 0, 16); err == nil {
933
			fv.SetInt(x)
934
			return nil
935
		}
936
	case reflect.Int32:
937
		if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
938
			fv.SetInt(x)
939
			return nil
940
		}
941

942
		if len(props.Enum) == 0 {
943
			break
944
		}
945
		m, ok := enumValueMaps[props.Enum]
946
		if !ok {
947
			break
948
		}
949
		x, ok := m[tok.value]
950
		if !ok {
951
			break
952
		}
953
		fv.SetInt(int64(x))
954
		return nil
955
	case reflect.Int64:
956
		if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
957
			fv.SetInt(x)
958
			return nil
959
		}
960

961
	case reflect.Ptr:
962
		// A basic field (indirected through pointer), or a repeated message/group
963
		p.back()
964
		fv.Set(reflect.New(fv.Type().Elem()))
965
		return p.readAny(fv.Elem(), props)
966
	case reflect.String:
967
		if tok.value[0] == '"' || tok.value[0] == '\'' {
968
			fv.SetString(tok.unquoted)
969
			return nil
970
		}
971
	case reflect.Struct:
972
		var terminator string
973
		switch tok.value {
974
		case "{":
975
			terminator = "}"
976
		case "<":
977
			terminator = ">"
978
		default:
979
			return p.errorf("expected '{' or '<', found %q", tok.value)
980
		}
981
		// TODO: Handle nested messages which implement encoding.TextUnmarshaler.
982
		return p.readStruct(fv, terminator)
983
	case reflect.Uint8:
984
		if x, err := strconv.ParseUint(tok.value, 0, 8); err == nil {
985
			fv.SetUint(x)
986
			return nil
987
		}
988
	case reflect.Uint16:
989
		if x, err := strconv.ParseUint(tok.value, 0, 16); err == nil {
990
			fv.SetUint(x)
991
			return nil
992
		}
993
	case reflect.Uint32:
994
		if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
995
			fv.SetUint(uint64(x))
996
			return nil
997
		}
998
	case reflect.Uint64:
999
		if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
1000
			fv.SetUint(x)
1001
			return nil
1002
		}
1003
	}
1004
	return p.errorf("invalid %v: %v", v.Type(), tok.value)
1005
}
1006

1007
// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
1008
// before starting to unmarshal, so any existing data in pb is always removed.
1009
// If a required field is not set and no other error occurs,
1010
// UnmarshalText returns *RequiredNotSetError.
1011
func UnmarshalText(s string, pb Message) error {
1012
	if um, ok := pb.(encoding.TextUnmarshaler); ok {
1013
		return um.UnmarshalText([]byte(s))
1014
	}
1015
	pb.Reset()
1016
	v := reflect.ValueOf(pb)
1017
	return newTextParser(s).readStruct(v.Elem(), "")
1018
}
1019

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.