github.com/gogo/protobuf@v1.3.2/proto/text_parser.go (about) 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 := ×tamp{} 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 }