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 37package proto 38 39// Functions for parsing the Text protocol buffer format. 40// TODO: message sets. 41 42import ( 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 54const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" 55 56type 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 62func (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 70type 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 78func (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 85type 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 93func 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 101func (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] 109func 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 123func isWhitespace(c byte) bool { 124 switch c { 125 case ' ', '\t', '\n', '\r': 126 return true 127 } 128 return false 129} 130 131func isQuote(c byte) bool { 132 switch c { 133 case '"', '\'': 134 return true 135 } 136 return false 137} 138 139func (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 163func (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 213var ( 214 errBadUTF8 = errors.New("proto: bad UTF-8") 215 errBadHex = errors.New("proto: bad hexadecimal") 216) 217 218func unquoteC(s string, quote rune) (string, error) { 219 // This is based on C++'s tokenizer.cc. 220 // Despite its name, this is *not* parsing C syntax. 221 // For instance, "\0" is an invalid quoted string. 222 223 // Avoid allocation in trivial cases. 224 simple := true 225 for _, r := range s { 226 if r == '\\' || r == quote { 227 simple = false 228 break 229 } 230 } 231 if simple { 232 return s, nil 233 } 234 235 buf := make([]byte, 0, 3*len(s)/2) 236 for len(s) > 0 { 237 r, n := utf8.DecodeRuneInString(s) 238 if r == utf8.RuneError && n == 1 { 239 return "", errBadUTF8 240 } 241 s = s[n:] 242 if r != '\\' { 243 if r < utf8.RuneSelf { 244 buf = append(buf, byte(r)) 245 } else { 246 buf = append(buf, string(r)...) 247 } 248 continue 249 } 250 251 ch, tail, err := unescape(s) 252 if err != nil { 253 return "", err 254 } 255 buf = append(buf, ch...) 256 s = tail 257 } 258 return string(buf), nil 259} 260 261func unescape(s string) (ch string, tail string, err error) { 262 r, n := utf8.DecodeRuneInString(s) 263 if r == utf8.RuneError && n == 1 { 264 return "", "", errBadUTF8 265 } 266 s = s[n:] 267 switch r { 268 case 'a': 269 return "\a", s, nil 270 case 'b': 271 return "\b", s, nil 272 case 'f': 273 return "\f", s, nil 274 case 'n': 275 return "\n", s, nil 276 case 'r': 277 return "\r", s, nil 278 case 't': 279 return "\t", s, nil 280 case 'v': 281 return "\v", s, nil 282 case '?': 283 return "?", s, nil // trigraph workaround 284 case '\'', '"', '\\': 285 return string(r), s, nil 286 case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X': 287 if len(s) < 2 { 288 return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) 289 } 290 base := 8 291 ss := s[:2] 292 s = s[2:] 293 if r == 'x' || r == 'X' { 294 base = 16 295 } else { 296 ss = string(r) + ss 297 } 298 i, err := strconv.ParseUint(ss, base, 8) 299 if err != nil { 300 return "", "", err 301 } 302 return string([]byte{byte(i)}), s, nil 303 case 'u', 'U': 304 n := 4 305 if r == 'U' { 306 n = 8 307 } 308 if len(s) < n { 309 return "", "", fmt.Errorf(`\%c requires %d digits`, r, n) 310 } 311 312 bs := make([]byte, n/2) 313 for i := 0; i < n; i += 2 { 314 a, ok1 := unhex(s[i]) 315 b, ok2 := unhex(s[i+1]) 316 if !ok1 || !ok2 { 317 return "", "", errBadHex 318 } 319 bs[i/2] = a<<4 | b 320 } 321 s = s[n:] 322 return string(bs), s, nil 323 } 324 return "", "", fmt.Errorf(`unknown escape \%c`, r) 325} 326 327// Adapted from src/pkg/strconv/quote.go. 328func unhex(b byte) (v byte, ok bool) { 329 switch { 330 case '0' <= b && b <= '9': 331 return b - '0', true 332 case 'a' <= b && b <= 'f': 333 return b - 'a' + 10, true 334 case 'A' <= b && b <= 'F': 335 return b - 'A' + 10, true 336 } 337 return 0, false 338} 339 340// Back off the parser by one token. Can only be done between calls to next(). 341// It makes the next advance() a no-op. 342func (p *textParser) back() { p.backed = true } 343 344// Advances the parser and returns the new current token. 345func (p *textParser) next() *token { 346 if p.backed || p.done { 347 p.backed = false 348 return &p.cur 349 } 350 p.advance() 351 if p.done { 352 p.cur.value = "" 353 } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { 354 // Look for multiple quoted strings separated by whitespace, 355 // and concatenate them. 356 cat := p.cur 357 for { 358 p.skipWhitespace() 359 if p.done || !isQuote(p.s[0]) { 360 break 361 } 362 p.advance() 363 if p.cur.err != nil { 364 return &p.cur 365 } 366 cat.value += " " + p.cur.value 367 cat.unquoted += p.cur.unquoted 368 } 369 p.done = false // parser may have seen EOF, but we want to return cat 370 p.cur = cat 371 } 372 return &p.cur 373} 374 375func (p *textParser) consumeToken(s string) error { 376 tok := p.next() 377 if tok.err != nil { 378 return tok.err 379 } 380 if tok.value != s { 381 p.back() 382 return p.errorf("expected %q, found %q", s, tok.value) 383 } 384 return nil 385} 386 387// Return a RequiredNotSetError indicating which required field was not set. 388func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { 389 st := sv.Type() 390 sprops := GetProperties(st) 391 for i := 0; i < st.NumField(); i++ { 392 if !isNil(sv.Field(i)) { 393 continue 394 } 395 396 props := sprops.Prop[i] 397 if props.Required { 398 return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} 399 } 400 } 401 return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", st)} // should not happen 402} 403 404// Returns the index in the struct for the named field, as well as the parsed tag properties. 405func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { 406 i, ok := sprops.decoderOrigNames[name] 407 if ok { 408 return i, sprops.Prop[i], true 409 } 410 return -1, nil, false 411} 412 413// Consume a ':' from the input stream (if the next token is a colon), 414// returning an error if a colon is needed but not present. 415func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { 416 tok := p.next() 417 if tok.err != nil { 418 return tok.err 419 } 420 if tok.value != ":" { 421 // Colon is optional when the field is a group or message. 422 needColon := true 423 switch props.Wire { 424 case "group": 425 needColon = false 426 case "bytes": 427 // A "bytes" field is either a message, a string, or a repeated field; 428 // those three become *T, *string and []T respectively, so we can check for 429 // this field being a pointer to a non-string. 430 if typ.Kind() == reflect.Ptr { 431 // *T or *string 432 if typ.Elem().Kind() == reflect.String { 433 break 434 } 435 } else if typ.Kind() == reflect.Slice { 436 // []T or []*T 437 if typ.Elem().Kind() != reflect.Ptr { 438 break 439 } 440 } else if typ.Kind() == reflect.String { 441 // The proto3 exception is for a string field, 442 // which requires a colon. 443 break 444 } 445 needColon = false 446 } 447 if needColon { 448 return p.errorf("expected ':', found %q", tok.value) 449 } 450 p.back() 451 } 452 return nil 453} 454 455func (p *textParser) readStruct(sv reflect.Value, terminator string) error { 456 st := sv.Type() 457 sprops := GetProperties(st) 458 reqCount := sprops.reqCount 459 var reqFieldErr error 460 fieldSet := make(map[string]bool) 461 // A struct is a sequence of "name: value", terminated by one of 462 // '>' or '}', or the end of the input. A name may also be 463 // "[extension]" or "[type/url]". 464 // 465 // The whole struct can also be an expanded Any message, like: 466 // [type/url] < ... struct contents ... > 467 for { 468 tok := p.next() 469 if tok.err != nil { 470 return tok.err 471 } 472 if tok.value == terminator { 473 break 474 } 475 if tok.value == "[" { 476 // Looks like an extension or an Any. 477 // 478 // TODO: Check whether we need to handle 479 // namespace rooted names (e.g. ".something.Foo"). 480 extName, err := p.consumeExtName() 481 if err != nil { 482 return err 483 } 484 485 if s := strings.LastIndex(extName, "/"); s >= 0 { 486 // If it contains a slash, it's an Any type URL. 487 messageName := extName[s+1:] 488 mt := MessageType(messageName) 489 if mt == nil { 490 return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) 491 } 492 tok = p.next() 493 if tok.err != nil { 494 return tok.err 495 } 496 // consume an optional colon 497 if tok.value == ":" { 498 tok = p.next() 499 if tok.err != nil { 500 return tok.err 501 } 502 } 503 var terminator string 504 switch tok.value { 505 case "<": 506 terminator = ">" 507 case "{": 508 terminator = "}" 509 default: 510 return p.errorf("expected '{' or '<', found %q", tok.value) 511 } 512 v := reflect.New(mt.Elem()) 513 if pe := p.readStruct(v.Elem(), terminator); pe != nil { 514 return pe 515 } 516 b, err := Marshal(v.Interface().(Message)) 517 if err != nil { 518 return p.errorf("failed to marshal message of type %q: %v", messageName, err) 519 } 520 if fieldSet["type_url"] { 521 return p.errorf(anyRepeatedlyUnpacked, "type_url") 522 } 523 if fieldSet["value"] { 524 return p.errorf(anyRepeatedlyUnpacked, "value") 525 } 526 sv.FieldByName("TypeUrl").SetString(extName) 527 sv.FieldByName("Value").SetBytes(b) 528 fieldSet["type_url"] = true 529 fieldSet["value"] = true 530 continue 531 } 532 533 var desc *ExtensionDesc 534 // This could be faster, but it's functional. 535 // TODO: Do something smarter than a linear scan. 536 for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { 537 if d.Name == extName { 538 desc = d 539 break 540 } 541 } 542 if desc == nil { 543 return p.errorf("unrecognized extension %q", extName) 544 } 545 546 props := &Properties{} 547 props.Parse(desc.Tag) 548 549 typ := reflect.TypeOf(desc.ExtensionType) 550 if err := p.checkForColon(props, typ); err != nil { 551 return err 552 } 553 554 rep := desc.repeated() 555 556 // Read the extension structure, and set it in 557 // the value we're constructing. 558 var ext reflect.Value 559 if !rep { 560 ext = reflect.New(typ).Elem() 561 } else { 562 ext = reflect.New(typ.Elem()).Elem() 563 } 564 if err := p.readAny(ext, props); err != nil { 565 if _, ok := err.(*RequiredNotSetError); !ok { 566 return err 567 } 568 reqFieldErr = err 569 } 570 ep := sv.Addr().Interface().(Message) 571 if !rep { 572 SetExtension(ep, desc, ext.Interface()) 573 } else { 574 old, err := GetExtension(ep, desc) 575 var sl reflect.Value 576 if err == nil { 577 sl = reflect.ValueOf(old) // existing slice 578 } else { 579 sl = reflect.MakeSlice(typ, 0, 1) 580 } 581 sl = reflect.Append(sl, ext) 582 SetExtension(ep, desc, sl.Interface()) 583 } 584 if err := p.consumeOptionalSeparator(); err != nil { 585 return err 586 } 587 continue 588 } 589 590 // This is a normal, non-extension field. 591 name := tok.value 592 var dst reflect.Value 593 fi, props, ok := structFieldByName(sprops, name) 594 if ok { 595 dst = sv.Field(fi) 596 } else if oop, ok := sprops.OneofTypes[name]; ok { 597 // It is a oneof. 598 props = oop.Prop 599 nv := reflect.New(oop.Type.Elem()) 600 dst = nv.Elem().Field(0) 601 field := sv.Field(oop.Field) 602 if !field.IsNil() { 603 return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) 604 } 605 field.Set(nv) 606 } 607 if !dst.IsValid() { 608 return p.errorf("unknown field name %q in %v", name, st) 609 } 610 611 if dst.Kind() == reflect.Map { 612 // Consume any colon. 613 if err := p.checkForColon(props, dst.Type()); err != nil { 614 return err 615 } 616 617 // Construct the map if it doesn't already exist. 618 if dst.IsNil() { 619 dst.Set(reflect.MakeMap(dst.Type())) 620 } 621 key := reflect.New(dst.Type().Key()).Elem() 622 val := reflect.New(dst.Type().Elem()).Elem() 623 624 // The map entry should be this sequence of tokens: 625 // < key : KEY value : VALUE > 626 // However, implementations may omit key or value, and technically 627 // we should support them in any order. See b/28924776 for a time 628 // this went wrong. 629 630 tok := p.next() 631 var terminator string 632 switch tok.value { 633 case "<": 634 terminator = ">" 635 case "{": 636 terminator = "}" 637 default: 638 return p.errorf("expected '{' or '<', found %q", tok.value) 639 } 640 for { 641 tok := p.next() 642 if tok.err != nil { 643 return tok.err 644 } 645 if tok.value == terminator { 646 break 647 } 648 switch tok.value { 649 case "key": 650 if err := p.consumeToken(":"); err != nil { 651 return err 652 } 653 if err := p.readAny(key, props.mkeyprop); err != nil { 654 return err 655 } 656 if err := p.consumeOptionalSeparator(); err != nil { 657 return err 658 } 659 case "value": 660 if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { 661 return err 662 } 663 if err := p.readAny(val, props.mvalprop); err != nil { 664 return err 665 } 666 if err := p.consumeOptionalSeparator(); err != nil { 667 return err 668 } 669 default: 670 p.back() 671 return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) 672 } 673 } 674 675 dst.SetMapIndex(key, val) 676 continue 677 } 678 679 // Check that it's not already set if it's not a repeated field. 680 if !props.Repeated && fieldSet[name] { 681 return p.errorf("non-repeated field %q was repeated", name) 682 } 683 684 if err := p.checkForColon(props, dst.Type()); err != nil { 685 return err 686 } 687 688 // Parse into the field. 689 fieldSet[name] = true 690 if err := p.readAny(dst, props); err != nil { 691 if _, ok := err.(*RequiredNotSetError); !ok { 692 return err 693 } 694 reqFieldErr = err 695 } 696 if props.Required { 697 reqCount-- 698 } 699 700 if err := p.consumeOptionalSeparator(); err != nil { 701 return err 702 } 703 704 } 705 706 if reqCount > 0 { 707 return p.missingRequiredFieldError(sv) 708 } 709 return reqFieldErr 710} 711 712// consumeExtName consumes extension name or expanded Any type URL and the 713// following ']'. It returns the name or URL consumed. 714func (p *textParser) consumeExtName() (string, error) { 715 tok := p.next() 716 if tok.err != nil { 717 return "", tok.err 718 } 719 720 // If extension name or type url is quoted, it's a single token. 721 if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { 722 name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) 723 if err != nil { 724 return "", err 725 } 726 return name, p.consumeToken("]") 727 } 728 729 // Consume everything up to "]" 730 var parts []string 731 for tok.value != "]" { 732 parts = append(parts, tok.value) 733 tok = p.next() 734 if tok.err != nil { 735 return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) 736 } 737 } 738 return strings.Join(parts, ""), nil 739} 740 741// consumeOptionalSeparator consumes an optional semicolon or comma. 742// It is used in readStruct to provide backward compatibility. 743func (p *textParser) consumeOptionalSeparator() error { 744 tok := p.next() 745 if tok.err != nil { 746 return tok.err 747 } 748 if tok.value != ";" && tok.value != "," { 749 p.back() 750 } 751 return nil 752} 753 754func (p *textParser) readAny(v reflect.Value, props *Properties) error { 755 tok := p.next() 756 if tok.err != nil { 757 return tok.err 758 } 759 if tok.value == "" { 760 return p.errorf("unexpected EOF") 761 } 762 if len(props.CustomType) > 0 { 763 if props.Repeated { 764 t := reflect.TypeOf(v.Interface()) 765 if t.Kind() == reflect.Slice { 766 tc := reflect.TypeOf(new(Marshaler)) 767 ok := t.Elem().Implements(tc.Elem()) 768 if ok { 769 fv := v 770 flen := fv.Len() 771 if flen == fv.Cap() { 772 nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1) 773 reflect.Copy(nav, fv) 774 fv.Set(nav) 775 } 776 fv.SetLen(flen + 1) 777 778 // Read one. 779 p.back() 780 return p.readAny(fv.Index(flen), props) 781 } 782 } 783 } 784 if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { 785 custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler) 786 err := custom.Unmarshal([]byte(tok.unquoted)) 787 if err != nil { 788 return p.errorf("%v %v: %v", err, v.Type(), tok.value) 789 } 790 v.Set(reflect.ValueOf(custom)) 791 } else { 792 custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler) 793 err := custom.Unmarshal([]byte(tok.unquoted)) 794 if err != nil { 795 return p.errorf("%v %v: %v", err, v.Type(), tok.value) 796 } 797 v.Set(reflect.Indirect(reflect.ValueOf(custom))) 798 } 799 return nil 800 } 801 if props.StdTime { 802 fv := v 803 p.back() 804 props.StdTime = false 805 tproto := ×tamp{} 806 err := p.readAny(reflect.ValueOf(tproto).Elem(), props) 807 props.StdTime = true 808 if err != nil { 809 return err 810 } 811 tim, err := timestampFromProto(tproto) 812 if err != nil { 813 return err 814 } 815 if props.Repeated { 816 t := reflect.TypeOf(v.Interface()) 817 if t.Kind() == reflect.Slice { 818 if t.Elem().Kind() == reflect.Ptr { 819 ts := fv.Interface().([]*time.Time) 820 ts = append(ts, &tim) 821 fv.Set(reflect.ValueOf(ts)) 822 return nil 823 } else { 824 ts := fv.Interface().([]time.Time) 825 ts = append(ts, tim) 826 fv.Set(reflect.ValueOf(ts)) 827 return nil 828 } 829 } 830 } 831 if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { 832 v.Set(reflect.ValueOf(&tim)) 833 } else { 834 v.Set(reflect.Indirect(reflect.ValueOf(&tim))) 835 } 836 return nil 837 } 838 if props.StdDuration { 839 fv := v 840 p.back() 841 props.StdDuration = false 842 dproto := &duration{} 843 err := p.readAny(reflect.ValueOf(dproto).Elem(), props) 844 props.StdDuration = true 845 if err != nil { 846 return err 847 } 848 dur, err := durationFromProto(dproto) 849 if err != nil { 850 return err 851 } 852 if props.Repeated { 853 t := reflect.TypeOf(v.Interface()) 854 if t.Kind() == reflect.Slice { 855 if t.Elem().Kind() == reflect.Ptr { 856 ds := fv.Interface().([]*time.Duration) 857 ds = append(ds, &dur) 858 fv.Set(reflect.ValueOf(ds)) 859 return nil 860 } else { 861 ds := fv.Interface().([]time.Duration) 862 ds = append(ds, dur) 863 fv.Set(reflect.ValueOf(ds)) 864 return nil 865 } 866 } 867 } 868 if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { 869 v.Set(reflect.ValueOf(&dur)) 870 } else { 871 v.Set(reflect.Indirect(reflect.ValueOf(&dur))) 872 } 873 return nil 874 } 875 switch fv := v; fv.Kind() { 876 case reflect.Slice: 877 at := v.Type() 878 if at.Elem().Kind() == reflect.Uint8 { 879 // Special case for []byte 880 if tok.value[0] != '"' && tok.value[0] != '\'' { 881 // Deliberately written out here, as the error after 882 // this switch statement would write "invalid []byte: ...", 883 // which is not as user-friendly. 884 return p.errorf("invalid string: %v", tok.value) 885 } 886 bytes := []byte(tok.unquoted) 887 fv.Set(reflect.ValueOf(bytes)) 888 return nil 889 } 890 // Repeated field. 891 if tok.value == "[" { 892 // Repeated field with list notation, like [1,2,3]. 893 for { 894 fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) 895 err := p.readAny(fv.Index(fv.Len()-1), props) 896 if err != nil { 897 return err 898 } 899 ntok := p.next() 900 if ntok.err != nil { 901 return ntok.err 902 } 903 if ntok.value == "]" { 904 break 905 } 906 if ntok.value != "," { 907 return p.errorf("Expected ']' or ',' found %q", ntok.value) 908 } 909 } 910 return nil 911 } 912 // One value of the repeated field. 913 p.back() 914 fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) 915 return p.readAny(fv.Index(fv.Len()-1), props) 916 case reflect.Bool: 917 // true/1/t/True or false/f/0/False. 918 switch tok.value { 919 case "true", "1", "t", "True": 920 fv.SetBool(true) 921 return nil 922 case "false", "0", "f", "False": 923 fv.SetBool(false) 924 return nil 925 } 926 case reflect.Float32, reflect.Float64: 927 v := tok.value 928 // Ignore 'f' for compatibility with output generated by C++, but don't 929 // remove 'f' when the value is "-inf" or "inf". 930 if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { 931 v = v[:len(v)-1] 932 } 933 if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { 934 fv.SetFloat(f) 935 return nil 936 } 937 case reflect.Int32: 938 if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { 939 fv.SetInt(x) 940 return nil 941 } 942 943 if len(props.Enum) == 0 { 944 break 945 } 946 m, ok := enumValueMaps[props.Enum] 947 if !ok { 948 break 949 } 950 x, ok := m[tok.value] 951 if !ok { 952 break 953 } 954 fv.SetInt(int64(x)) 955 return nil 956 case reflect.Int64: 957 if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { 958 fv.SetInt(x) 959 return nil 960 } 961 962 case reflect.Ptr: 963 // A basic field (indirected through pointer), or a repeated message/group 964 p.back() 965 fv.Set(reflect.New(fv.Type().Elem())) 966 return p.readAny(fv.Elem(), props) 967 case reflect.String: 968 if tok.value[0] == '"' || tok.value[0] == '\'' { 969 fv.SetString(tok.unquoted) 970 return nil 971 } 972 case reflect.Struct: 973 var terminator string 974 switch tok.value { 975 case "{": 976 terminator = "}" 977 case "<": 978 terminator = ">" 979 default: 980 return p.errorf("expected '{' or '<', found %q", tok.value) 981 } 982 // TODO: Handle nested messages which implement encoding.TextUnmarshaler. 983 return p.readStruct(fv, terminator) 984 case reflect.Uint32: 985 if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { 986 fv.SetUint(x) 987 return nil 988 } 989 case reflect.Uint64: 990 if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { 991 fv.SetUint(x) 992 return nil 993 } 994 } 995 return p.errorf("invalid %v: %v", v.Type(), tok.value) 996} 997 998// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb 999// before starting to unmarshal, so any existing data in pb is always removed. 1000// If a required field is not set and no other error occurs, 1001// UnmarshalText returns *RequiredNotSetError. 1002func UnmarshalText(s string, pb Message) error { 1003 if um, ok := pb.(encoding.TextUnmarshaler); ok { 1004 err := um.UnmarshalText([]byte(s)) 1005 return err 1006 } 1007 pb.Reset() 1008 v := reflect.ValueOf(pb) 1009 if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { 1010 return pe 1011 } 1012 return nil 1013} 1014