OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / golang / protobuf / proto / text_parser.go
1 // Go support for Protocol Buffers - Google's data interchange format
2 //
3 // Copyright 2010 The Go Authors.  All rights reserved.
4 // https://github.com/golang/protobuf
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 package proto
33
34 // Functions for parsing the Text protocol buffer format.
35 // TODO: message sets.
36
37 import (
38         "encoding"
39         "errors"
40         "fmt"
41         "reflect"
42         "strconv"
43         "strings"
44         "unicode/utf8"
45 )
46
47 // Error string emitted when deserializing Any and fields are already set
48 const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
49
50 type ParseError struct {
51         Message string
52         Line    int // 1-based line number
53         Offset  int // 0-based byte offset from start of input
54 }
55
56 func (p *ParseError) Error() string {
57         if p.Line == 1 {
58                 // show offset only for first line
59                 return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
60         }
61         return fmt.Sprintf("line %d: %v", p.Line, p.Message)
62 }
63
64 type token struct {
65         value    string
66         err      *ParseError
67         line     int    // line number
68         offset   int    // byte number from start of input, not start of line
69         unquoted string // the unquoted version of value, if it was a quoted string
70 }
71
72 func (t *token) String() string {
73         if t.err == nil {
74                 return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset)
75         }
76         return fmt.Sprintf("parse error: %v", t.err)
77 }
78
79 type textParser struct {
80         s            string // remaining input
81         done         bool   // whether the parsing is finished (success or error)
82         backed       bool   // whether back() was called
83         offset, line int
84         cur          token
85 }
86
87 func newTextParser(s string) *textParser {
88         p := new(textParser)
89         p.s = s
90         p.line = 1
91         p.cur.line = 1
92         return p
93 }
94
95 func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
96         pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
97         p.cur.err = pe
98         p.done = true
99         return pe
100 }
101
102 // Numbers and identifiers are matched by [-+._A-Za-z0-9]
103 func isIdentOrNumberChar(c byte) bool {
104         switch {
105         case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
106                 return true
107         case '0' <= c && c <= '9':
108                 return true
109         }
110         switch c {
111         case '-', '+', '.', '_':
112                 return true
113         }
114         return false
115 }
116
117 func isWhitespace(c byte) bool {
118         switch c {
119         case ' ', '\t', '\n', '\r':
120                 return true
121         }
122         return false
123 }
124
125 func isQuote(c byte) bool {
126         switch c {
127         case '"', '\'':
128                 return true
129         }
130         return false
131 }
132
133 func (p *textParser) skipWhitespace() {
134         i := 0
135         for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
136                 if p.s[i] == '#' {
137                         // comment; skip to end of line or input
138                         for i < len(p.s) && p.s[i] != '\n' {
139                                 i++
140                         }
141                         if i == len(p.s) {
142                                 break
143                         }
144                 }
145                 if p.s[i] == '\n' {
146                         p.line++
147                 }
148                 i++
149         }
150         p.offset += i
151         p.s = p.s[i:len(p.s)]
152         if len(p.s) == 0 {
153                 p.done = true
154         }
155 }
156
157 func (p *textParser) advance() {
158         // Skip whitespace
159         p.skipWhitespace()
160         if p.done {
161                 return
162         }
163
164         // Start of non-whitespace
165         p.cur.err = nil
166         p.cur.offset, p.cur.line = p.offset, p.line
167         p.cur.unquoted = ""
168         switch p.s[0] {
169         case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
170                 // Single symbol
171                 p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
172         case '"', '\'':
173                 // Quoted string
174                 i := 1
175                 for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
176                         if p.s[i] == '\\' && i+1 < len(p.s) {
177                                 // skip escaped char
178                                 i++
179                         }
180                         i++
181                 }
182                 if i >= len(p.s) || p.s[i] != p.s[0] {
183                         p.errorf("unmatched quote")
184                         return
185                 }
186                 unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
187                 if err != nil {
188                         p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
189                         return
190                 }
191                 p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
192                 p.cur.unquoted = unq
193         default:
194                 i := 0
195                 for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
196                         i++
197                 }
198                 if i == 0 {
199                         p.errorf("unexpected byte %#x", p.s[0])
200                         return
201                 }
202                 p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
203         }
204         p.offset += len(p.cur.value)
205 }
206
207 var (
208         errBadUTF8 = errors.New("proto: bad UTF-8")
209         errBadHex  = errors.New("proto: bad hexadecimal")
210 )
211
212 func unquoteC(s string, quote rune) (string, error) {
213         // This is based on C++'s tokenizer.cc.
214         // Despite its name, this is *not* parsing C syntax.
215         // For instance, "\0" is an invalid quoted string.
216
217         // Avoid allocation in trivial cases.
218         simple := true
219         for _, r := range s {
220                 if r == '\\' || r == quote {
221                         simple = false
222                         break
223                 }
224         }
225         if simple {
226                 return s, nil
227         }
228
229         buf := make([]byte, 0, 3*len(s)/2)
230         for len(s) > 0 {
231                 r, n := utf8.DecodeRuneInString(s)
232                 if r == utf8.RuneError && n == 1 {
233                         return "", errBadUTF8
234                 }
235                 s = s[n:]
236                 if r != '\\' {
237                         if r < utf8.RuneSelf {
238                                 buf = append(buf, byte(r))
239                         } else {
240                                 buf = append(buf, string(r)...)
241                         }
242                         continue
243                 }
244
245                 ch, tail, err := unescape(s)
246                 if err != nil {
247                         return "", err
248                 }
249                 buf = append(buf, ch...)
250                 s = tail
251         }
252         return string(buf), nil
253 }
254
255 func unescape(s string) (ch string, tail string, err error) {
256         r, n := utf8.DecodeRuneInString(s)
257         if r == utf8.RuneError && n == 1 {
258                 return "", "", errBadUTF8
259         }
260         s = s[n:]
261         switch r {
262         case 'a':
263                 return "\a", s, nil
264         case 'b':
265                 return "\b", s, nil
266         case 'f':
267                 return "\f", s, nil
268         case 'n':
269                 return "\n", s, nil
270         case 'r':
271                 return "\r", s, nil
272         case 't':
273                 return "\t", s, nil
274         case 'v':
275                 return "\v", s, nil
276         case '?':
277                 return "?", s, nil // trigraph workaround
278         case '\'', '"', '\\':
279                 return string(r), s, nil
280         case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
281                 if len(s) < 2 {
282                         return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
283                 }
284                 base := 8
285                 ss := s[:2]
286                 s = s[2:]
287                 if r == 'x' || r == 'X' {
288                         base = 16
289                 } else {
290                         ss = string(r) + ss
291                 }
292                 i, err := strconv.ParseUint(ss, base, 8)
293                 if err != nil {
294                         return "", "", err
295                 }
296                 return string([]byte{byte(i)}), s, nil
297         case 'u', 'U':
298                 n := 4
299                 if r == 'U' {
300                         n = 8
301                 }
302                 if len(s) < n {
303                         return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
304                 }
305
306                 bs := make([]byte, n/2)
307                 for i := 0; i < n; i += 2 {
308                         a, ok1 := unhex(s[i])
309                         b, ok2 := unhex(s[i+1])
310                         if !ok1 || !ok2 {
311                                 return "", "", errBadHex
312                         }
313                         bs[i/2] = a<<4 | b
314                 }
315                 s = s[n:]
316                 return string(bs), s, nil
317         }
318         return "", "", fmt.Errorf(`unknown escape \%c`, r)
319 }
320
321 // Adapted from src/pkg/strconv/quote.go.
322 func unhex(b byte) (v byte, ok bool) {
323         switch {
324         case '0' <= b && b <= '9':
325                 return b - '0', true
326         case 'a' <= b && b <= 'f':
327                 return b - 'a' + 10, true
328         case 'A' <= b && b <= 'F':
329                 return b - 'A' + 10, true
330         }
331         return 0, false
332 }
333
334 // Back off the parser by one token. Can only be done between calls to next().
335 // It makes the next advance() a no-op.
336 func (p *textParser) back() { p.backed = true }
337
338 // Advances the parser and returns the new current token.
339 func (p *textParser) next() *token {
340         if p.backed || p.done {
341                 p.backed = false
342                 return &p.cur
343         }
344         p.advance()
345         if p.done {
346                 p.cur.value = ""
347         } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {
348                 // Look for multiple quoted strings separated by whitespace,
349                 // and concatenate them.
350                 cat := p.cur
351                 for {
352                         p.skipWhitespace()
353                         if p.done || !isQuote(p.s[0]) {
354                                 break
355                         }
356                         p.advance()
357                         if p.cur.err != nil {
358                                 return &p.cur
359                         }
360                         cat.value += " " + p.cur.value
361                         cat.unquoted += p.cur.unquoted
362                 }
363                 p.done = false // parser may have seen EOF, but we want to return cat
364                 p.cur = cat
365         }
366         return &p.cur
367 }
368
369 func (p *textParser) consumeToken(s string) error {
370         tok := p.next()
371         if tok.err != nil {
372                 return tok.err
373         }
374         if tok.value != s {
375                 p.back()
376                 return p.errorf("expected %q, found %q", s, tok.value)
377         }
378         return nil
379 }
380
381 // Return a RequiredNotSetError indicating which required field was not set.
382 func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
383         st := sv.Type()
384         sprops := GetProperties(st)
385         for i := 0; i < st.NumField(); i++ {
386                 if !isNil(sv.Field(i)) {
387                         continue
388                 }
389
390                 props := sprops.Prop[i]
391                 if props.Required {
392                         return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
393                 }
394         }
395         return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", st)} // should not happen
396 }
397
398 // Returns the index in the struct for the named field, as well as the parsed tag properties.
399 func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
400         i, ok := sprops.decoderOrigNames[name]
401         if ok {
402                 return i, sprops.Prop[i], true
403         }
404         return -1, nil, false
405 }
406
407 // Consume a ':' from the input stream (if the next token is a colon),
408 // returning an error if a colon is needed but not present.
409 func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
410         tok := p.next()
411         if tok.err != nil {
412                 return tok.err
413         }
414         if tok.value != ":" {
415                 // Colon is optional when the field is a group or message.
416                 needColon := true
417                 switch props.Wire {
418                 case "group":
419                         needColon = false
420                 case "bytes":
421                         // A "bytes" field is either a message, a string, or a repeated field;
422                         // those three become *T, *string and []T respectively, so we can check for
423                         // this field being a pointer to a non-string.
424                         if typ.Kind() == reflect.Ptr {
425                                 // *T or *string
426                                 if typ.Elem().Kind() == reflect.String {
427                                         break
428                                 }
429                         } else if typ.Kind() == reflect.Slice {
430                                 // []T or []*T
431                                 if typ.Elem().Kind() != reflect.Ptr {
432                                         break
433                                 }
434                         } else if typ.Kind() == reflect.String {
435                                 // The proto3 exception is for a string field,
436                                 // which requires a colon.
437                                 break
438                         }
439                         needColon = false
440                 }
441                 if needColon {
442                         return p.errorf("expected ':', found %q", tok.value)
443                 }
444                 p.back()
445         }
446         return nil
447 }
448
449 func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
450         st := sv.Type()
451         sprops := GetProperties(st)
452         reqCount := sprops.reqCount
453         var reqFieldErr error
454         fieldSet := make(map[string]bool)
455         // A struct is a sequence of "name: value", terminated by one of
456         // '>' or '}', or the end of the input.  A name may also be
457         // "[extension]" or "[type/url]".
458         //
459         // The whole struct can also be an expanded Any message, like:
460         // [type/url] < ... struct contents ... >
461         for {
462                 tok := p.next()
463                 if tok.err != nil {
464                         return tok.err
465                 }
466                 if tok.value == terminator {
467                         break
468                 }
469                 if tok.value == "[" {
470                         // Looks like an extension or an Any.
471                         //
472                         // TODO: Check whether we need to handle
473                         // namespace rooted names (e.g. ".something.Foo").
474                         extName, err := p.consumeExtName()
475                         if err != nil {
476                                 return err
477                         }
478
479                         if s := strings.LastIndex(extName, "/"); s >= 0 {
480                                 // If it contains a slash, it's an Any type URL.
481                                 messageName := extName[s+1:]
482                                 mt := MessageType(messageName)
483                                 if mt == nil {
484                                         return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
485                                 }
486                                 tok = p.next()
487                                 if tok.err != nil {
488                                         return tok.err
489                                 }
490                                 // consume an optional colon
491                                 if tok.value == ":" {
492                                         tok = p.next()
493                                         if tok.err != nil {
494                                                 return tok.err
495                                         }
496                                 }
497                                 var terminator string
498                                 switch tok.value {
499                                 case "<":
500                                         terminator = ">"
501                                 case "{":
502                                         terminator = "}"
503                                 default:
504                                         return p.errorf("expected '{' or '<', found %q", tok.value)
505                                 }
506                                 v := reflect.New(mt.Elem())
507                                 if pe := p.readStruct(v.Elem(), terminator); pe != nil {
508                                         return pe
509                                 }
510                                 b, err := Marshal(v.Interface().(Message))
511                                 if err != nil {
512                                         return p.errorf("failed to marshal message of type %q: %v", messageName, err)
513                                 }
514                                 if fieldSet["type_url"] {
515                                         return p.errorf(anyRepeatedlyUnpacked, "type_url")
516                                 }
517                                 if fieldSet["value"] {
518                                         return p.errorf(anyRepeatedlyUnpacked, "value")
519                                 }
520                                 sv.FieldByName("TypeUrl").SetString(extName)
521                                 sv.FieldByName("Value").SetBytes(b)
522                                 fieldSet["type_url"] = true
523                                 fieldSet["value"] = true
524                                 continue
525                         }
526
527                         var desc *ExtensionDesc
528                         // This could be faster, but it's functional.
529                         // TODO: Do something smarter than a linear scan.
530                         for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
531                                 if d.Name == extName {
532                                         desc = d
533                                         break
534                                 }
535                         }
536                         if desc == nil {
537                                 return p.errorf("unrecognized extension %q", extName)
538                         }
539
540                         props := &Properties{}
541                         props.Parse(desc.Tag)
542
543                         typ := reflect.TypeOf(desc.ExtensionType)
544                         if err := p.checkForColon(props, typ); err != nil {
545                                 return err
546                         }
547
548                         rep := desc.repeated()
549
550                         // Read the extension structure, and set it in
551                         // the value we're constructing.
552                         var ext reflect.Value
553                         if !rep {
554                                 ext = reflect.New(typ).Elem()
555                         } else {
556                                 ext = reflect.New(typ.Elem()).Elem()
557                         }
558                         if err := p.readAny(ext, props); err != nil {
559                                 if _, ok := err.(*RequiredNotSetError); !ok {
560                                         return err
561                                 }
562                                 reqFieldErr = err
563                         }
564                         ep := sv.Addr().Interface().(Message)
565                         if !rep {
566                                 SetExtension(ep, desc, ext.Interface())
567                         } else {
568                                 old, err := GetExtension(ep, desc)
569                                 var sl reflect.Value
570                                 if err == nil {
571                                         sl = reflect.ValueOf(old) // existing slice
572                                 } else {
573                                         sl = reflect.MakeSlice(typ, 0, 1)
574                                 }
575                                 sl = reflect.Append(sl, ext)
576                                 SetExtension(ep, desc, sl.Interface())
577                         }
578                         if err := p.consumeOptionalSeparator(); err != nil {
579                                 return err
580                         }
581                         continue
582                 }
583
584                 // This is a normal, non-extension field.
585                 name := tok.value
586                 var dst reflect.Value
587                 fi, props, ok := structFieldByName(sprops, name)
588                 if ok {
589                         dst = sv.Field(fi)
590                 } else if oop, ok := sprops.OneofTypes[name]; ok {
591                         // It is a oneof.
592                         props = oop.Prop
593                         nv := reflect.New(oop.Type.Elem())
594                         dst = nv.Elem().Field(0)
595                         field := sv.Field(oop.Field)
596                         if !field.IsNil() {
597                                 return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
598                         }
599                         field.Set(nv)
600                 }
601                 if !dst.IsValid() {
602                         return p.errorf("unknown field name %q in %v", name, st)
603                 }
604
605                 if dst.Kind() == reflect.Map {
606                         // Consume any colon.
607                         if err := p.checkForColon(props, dst.Type()); err != nil {
608                                 return err
609                         }
610
611                         // Construct the map if it doesn't already exist.
612                         if dst.IsNil() {
613                                 dst.Set(reflect.MakeMap(dst.Type()))
614                         }
615                         key := reflect.New(dst.Type().Key()).Elem()
616                         val := reflect.New(dst.Type().Elem()).Elem()
617
618                         // The map entry should be this sequence of tokens:
619                         //      < key : KEY value : VALUE >
620                         // However, implementations may omit key or value, and technically
621                         // we should support them in any order.  See b/28924776 for a time
622                         // this went wrong.
623
624                         tok := p.next()
625                         var terminator string
626                         switch tok.value {
627                         case "<":
628                                 terminator = ">"
629                         case "{":
630                                 terminator = "}"
631                         default:
632                                 return p.errorf("expected '{' or '<', found %q", tok.value)
633                         }
634                         for {
635                                 tok := p.next()
636                                 if tok.err != nil {
637                                         return tok.err
638                                 }
639                                 if tok.value == terminator {
640                                         break
641                                 }
642                                 switch tok.value {
643                                 case "key":
644                                         if err := p.consumeToken(":"); err != nil {
645                                                 return err
646                                         }
647                                         if err := p.readAny(key, props.mkeyprop); err != nil {
648                                                 return err
649                                         }
650                                         if err := p.consumeOptionalSeparator(); err != nil {
651                                                 return err
652                                         }
653                                 case "value":
654                                         if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
655                                                 return err
656                                         }
657                                         if err := p.readAny(val, props.mvalprop); err != nil {
658                                                 return err
659                                         }
660                                         if err := p.consumeOptionalSeparator(); err != nil {
661                                                 return err
662                                         }
663                                 default:
664                                         p.back()
665                                         return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
666                                 }
667                         }
668
669                         dst.SetMapIndex(key, val)
670                         continue
671                 }
672
673                 // Check that it's not already set if it's not a repeated field.
674                 if !props.Repeated && fieldSet[name] {
675                         return p.errorf("non-repeated field %q was repeated", name)
676                 }
677
678                 if err := p.checkForColon(props, dst.Type()); err != nil {
679                         return err
680                 }
681
682                 // Parse into the field.
683                 fieldSet[name] = true
684                 if err := p.readAny(dst, props); err != nil {
685                         if _, ok := err.(*RequiredNotSetError); !ok {
686                                 return err
687                         }
688                         reqFieldErr = err
689                 }
690                 if props.Required {
691                         reqCount--
692                 }
693
694                 if err := p.consumeOptionalSeparator(); err != nil {
695                         return err
696                 }
697
698         }
699
700         if reqCount > 0 {
701                 return p.missingRequiredFieldError(sv)
702         }
703         return reqFieldErr
704 }
705
706 // consumeExtName consumes extension name or expanded Any type URL and the
707 // following ']'. It returns the name or URL consumed.
708 func (p *textParser) consumeExtName() (string, error) {
709         tok := p.next()
710         if tok.err != nil {
711                 return "", tok.err
712         }
713
714         // If extension name or type url is quoted, it's a single token.
715         if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
716                 name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
717                 if err != nil {
718                         return "", err
719                 }
720                 return name, p.consumeToken("]")
721         }
722
723         // Consume everything up to "]"
724         var parts []string
725         for tok.value != "]" {
726                 parts = append(parts, tok.value)
727                 tok = p.next()
728                 if tok.err != nil {
729                         return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
730                 }
731         }
732         return strings.Join(parts, ""), nil
733 }
734
735 // consumeOptionalSeparator consumes an optional semicolon or comma.
736 // It is used in readStruct to provide backward compatibility.
737 func (p *textParser) consumeOptionalSeparator() error {
738         tok := p.next()
739         if tok.err != nil {
740                 return tok.err
741         }
742         if tok.value != ";" && tok.value != "," {
743                 p.back()
744         }
745         return nil
746 }
747
748 func (p *textParser) readAny(v reflect.Value, props *Properties) error {
749         tok := p.next()
750         if tok.err != nil {
751                 return tok.err
752         }
753         if tok.value == "" {
754                 return p.errorf("unexpected EOF")
755         }
756
757         switch fv := v; fv.Kind() {
758         case reflect.Slice:
759                 at := v.Type()
760                 if at.Elem().Kind() == reflect.Uint8 {
761                         // Special case for []byte
762                         if tok.value[0] != '"' && tok.value[0] != '\'' {
763                                 // Deliberately written out here, as the error after
764                                 // this switch statement would write "invalid []byte: ...",
765                                 // which is not as user-friendly.
766                                 return p.errorf("invalid string: %v", tok.value)
767                         }
768                         bytes := []byte(tok.unquoted)
769                         fv.Set(reflect.ValueOf(bytes))
770                         return nil
771                 }
772                 // Repeated field.
773                 if tok.value == "[" {
774                         // Repeated field with list notation, like [1,2,3].
775                         for {
776                                 fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
777                                 err := p.readAny(fv.Index(fv.Len()-1), props)
778                                 if err != nil {
779                                         return err
780                                 }
781                                 tok := p.next()
782                                 if tok.err != nil {
783                                         return tok.err
784                                 }
785                                 if tok.value == "]" {
786                                         break
787                                 }
788                                 if tok.value != "," {
789                                         return p.errorf("Expected ']' or ',' found %q", tok.value)
790                                 }
791                         }
792                         return nil
793                 }
794                 // One value of the repeated field.
795                 p.back()
796                 fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
797                 return p.readAny(fv.Index(fv.Len()-1), props)
798         case reflect.Bool:
799                 // true/1/t/True or false/f/0/False.
800                 switch tok.value {
801                 case "true", "1", "t", "True":
802                         fv.SetBool(true)
803                         return nil
804                 case "false", "0", "f", "False":
805                         fv.SetBool(false)
806                         return nil
807                 }
808         case reflect.Float32, reflect.Float64:
809                 v := tok.value
810                 // Ignore 'f' for compatibility with output generated by C++, but don't
811                 // remove 'f' when the value is "-inf" or "inf".
812                 if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
813                         v = v[:len(v)-1]
814                 }
815                 if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
816                         fv.SetFloat(f)
817                         return nil
818                 }
819         case reflect.Int32:
820                 if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
821                         fv.SetInt(x)
822                         return nil
823                 }
824
825                 if len(props.Enum) == 0 {
826                         break
827                 }
828                 m, ok := enumValueMaps[props.Enum]
829                 if !ok {
830                         break
831                 }
832                 x, ok := m[tok.value]
833                 if !ok {
834                         break
835                 }
836                 fv.SetInt(int64(x))
837                 return nil
838         case reflect.Int64:
839                 if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
840                         fv.SetInt(x)
841                         return nil
842                 }
843
844         case reflect.Ptr:
845                 // A basic field (indirected through pointer), or a repeated message/group
846                 p.back()
847                 fv.Set(reflect.New(fv.Type().Elem()))
848                 return p.readAny(fv.Elem(), props)
849         case reflect.String:
850                 if tok.value[0] == '"' || tok.value[0] == '\'' {
851                         fv.SetString(tok.unquoted)
852                         return nil
853                 }
854         case reflect.Struct:
855                 var terminator string
856                 switch tok.value {
857                 case "{":
858                         terminator = "}"
859                 case "<":
860                         terminator = ">"
861                 default:
862                         return p.errorf("expected '{' or '<', found %q", tok.value)
863                 }
864                 // TODO: Handle nested messages which implement encoding.TextUnmarshaler.
865                 return p.readStruct(fv, terminator)
866         case reflect.Uint32:
867                 if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
868                         fv.SetUint(x)
869                         return nil
870                 }
871         case reflect.Uint64:
872                 if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
873                         fv.SetUint(x)
874                         return nil
875                 }
876         }
877         return p.errorf("invalid %v: %v", v.Type(), tok.value)
878 }
879
880 // UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
881 // before starting to unmarshal, so any existing data in pb is always removed.
882 // If a required field is not set and no other error occurs,
883 // UnmarshalText returns *RequiredNotSetError.
884 func UnmarshalText(s string, pb Message) error {
885         if um, ok := pb.(encoding.TextUnmarshaler); ok {
886                 err := um.UnmarshalText([]byte(s))
887                 return err
888         }
889         pb.Reset()
890         v := reflect.ValueOf(pb)
891         if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
892                 return pe
893         }
894         return nil
895 }