text_parser.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. // Extensions for Protocol Buffers to create more go like structures.
  2. //
  3. // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
  4. // http://code.google.com/p/gogoprotobuf/gogoproto
  5. //
  6. // Go support for Protocol Buffers - Google's data interchange format
  7. //
  8. // Copyright 2010 The Go Authors. All rights reserved.
  9. // http://code.google.com/p/goprotobuf/
  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. package proto
  37. // Functions for parsing the Text protocol buffer format.
  38. // TODO: message sets.
  39. import (
  40. "errors"
  41. "fmt"
  42. "reflect"
  43. "strconv"
  44. "strings"
  45. "unicode/utf8"
  46. )
  47. // textUnmarshaler is implemented by Messages that can unmarshal themsleves.
  48. // It is identical to encoding.TextUnmarshaler, introduced in go 1.2,
  49. // which will eventually replace it.
  50. type textUnmarshaler interface {
  51. UnmarshalText(text []byte) error
  52. }
  53. type ParseError struct {
  54. Message string
  55. Line int // 1-based line number
  56. Offset int // 0-based byte offset from start of input
  57. }
  58. func (p *ParseError) Error() string {
  59. if p.Line == 1 {
  60. // show offset only for first line
  61. return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
  62. }
  63. return fmt.Sprintf("line %d: %v", p.Line, p.Message)
  64. }
  65. type token struct {
  66. value string
  67. err *ParseError
  68. line int // line number
  69. offset int // byte number from start of input, not start of line
  70. unquoted string // the unquoted version of value, if it was a quoted string
  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. type textParser struct {
  79. s string // remaining input
  80. done bool // whether the parsing is finished (success or error)
  81. backed bool // whether back() was called
  82. offset, line int
  83. cur token
  84. }
  85. func newTextParser(s string) *textParser {
  86. p := new(textParser)
  87. p.s = s
  88. p.line = 1
  89. p.cur.line = 1
  90. return p
  91. }
  92. func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
  93. pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
  94. p.cur.err = pe
  95. p.done = true
  96. return pe
  97. }
  98. // Numbers and identifiers are matched by [-+._A-Za-z0-9]
  99. func isIdentOrNumberChar(c byte) bool {
  100. switch {
  101. case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
  102. return true
  103. case '0' <= c && c <= '9':
  104. return true
  105. }
  106. switch c {
  107. case '-', '+', '.', '_':
  108. return true
  109. }
  110. return false
  111. }
  112. func isWhitespace(c byte) bool {
  113. switch c {
  114. case ' ', '\t', '\n', '\r':
  115. return true
  116. }
  117. return false
  118. }
  119. func (p *textParser) skipWhitespace() {
  120. i := 0
  121. for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
  122. if p.s[i] == '#' {
  123. // comment; skip to end of line or input
  124. for i < len(p.s) && p.s[i] != '\n' {
  125. i++
  126. }
  127. if i == len(p.s) {
  128. break
  129. }
  130. }
  131. if p.s[i] == '\n' {
  132. p.line++
  133. }
  134. i++
  135. }
  136. p.offset += i
  137. p.s = p.s[i:len(p.s)]
  138. if len(p.s) == 0 {
  139. p.done = true
  140. }
  141. }
  142. func (p *textParser) advance() {
  143. // Skip whitespace
  144. p.skipWhitespace()
  145. if p.done {
  146. return
  147. }
  148. // Start of non-whitespace
  149. p.cur.err = nil
  150. p.cur.offset, p.cur.line = p.offset, p.line
  151. p.cur.unquoted = ""
  152. switch p.s[0] {
  153. case '<', '>', '{', '}', ':', '[', ']', ';', ',':
  154. // Single symbol
  155. p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
  156. case '"', '\'':
  157. // Quoted string
  158. i := 1
  159. for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
  160. if p.s[i] == '\\' && i+1 < len(p.s) {
  161. // skip escaped char
  162. i++
  163. }
  164. i++
  165. }
  166. if i >= len(p.s) || p.s[i] != p.s[0] {
  167. p.errorf("unmatched quote")
  168. return
  169. }
  170. unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
  171. if err != nil {
  172. p.errorf("invalid quoted string %v", p.s[0:i+1])
  173. return
  174. }
  175. p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
  176. p.cur.unquoted = unq
  177. default:
  178. i := 0
  179. for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
  180. i++
  181. }
  182. if i == 0 {
  183. p.errorf("unexpected byte %#x", p.s[0])
  184. return
  185. }
  186. p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
  187. }
  188. p.offset += len(p.cur.value)
  189. }
  190. var (
  191. errBadUTF8 = errors.New("proto: bad UTF-8")
  192. errBadHex = errors.New("proto: bad hexadecimal")
  193. )
  194. func unquoteC(s string, quote rune) (string, error) {
  195. // This is based on C++'s tokenizer.cc.
  196. // Despite its name, this is *not* parsing C syntax.
  197. // For instance, "\0" is an invalid quoted string.
  198. // Avoid allocation in trivial cases.
  199. simple := true
  200. for _, r := range s {
  201. if r == '\\' || r == quote {
  202. simple = false
  203. break
  204. }
  205. }
  206. if simple {
  207. return s, nil
  208. }
  209. buf := make([]byte, 0, 3*len(s)/2)
  210. for len(s) > 0 {
  211. r, n := utf8.DecodeRuneInString(s)
  212. if r == utf8.RuneError && n == 1 {
  213. return "", errBadUTF8
  214. }
  215. s = s[n:]
  216. if r != '\\' {
  217. if r < utf8.RuneSelf {
  218. buf = append(buf, byte(r))
  219. } else {
  220. buf = append(buf, string(r)...)
  221. }
  222. continue
  223. }
  224. ch, tail, err := unescape(s)
  225. if err != nil {
  226. return "", err
  227. }
  228. buf = append(buf, ch...)
  229. s = tail
  230. }
  231. return string(buf), nil
  232. }
  233. func unescape(s string) (ch string, tail string, err error) {
  234. r, n := utf8.DecodeRuneInString(s)
  235. if r == utf8.RuneError && n == 1 {
  236. return "", "", errBadUTF8
  237. }
  238. s = s[n:]
  239. switch r {
  240. case 'a':
  241. return "\a", s, nil
  242. case 'b':
  243. return "\b", s, nil
  244. case 'f':
  245. return "\f", s, nil
  246. case 'n':
  247. return "\n", s, nil
  248. case 'r':
  249. return "\r", s, nil
  250. case 't':
  251. return "\t", s, nil
  252. case 'v':
  253. return "\v", s, nil
  254. case '?':
  255. return "?", s, nil // trigraph workaround
  256. case '\'', '"', '\\':
  257. return string(r), s, nil
  258. case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
  259. if len(s) < 2 {
  260. return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
  261. }
  262. base := 8
  263. ss := s[:2]
  264. s = s[2:]
  265. if r == 'x' || r == 'X' {
  266. base = 16
  267. } else {
  268. ss = string(r) + ss
  269. }
  270. i, err := strconv.ParseUint(ss, base, 8)
  271. if err != nil {
  272. return "", "", err
  273. }
  274. return string([]byte{byte(i)}), s, nil
  275. case 'u', 'U':
  276. n := 4
  277. if r == 'U' {
  278. n = 8
  279. }
  280. if len(s) < n {
  281. return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
  282. }
  283. bs := make([]byte, n/2)
  284. for i := 0; i < n; i += 2 {
  285. a, ok1 := unhex(s[i])
  286. b, ok2 := unhex(s[i+1])
  287. if !ok1 || !ok2 {
  288. return "", "", errBadHex
  289. }
  290. bs[i/2] = a<<4 | b
  291. }
  292. s = s[n:]
  293. return string(bs), s, nil
  294. }
  295. return "", "", fmt.Errorf(`unknown escape \%c`, r)
  296. }
  297. // Adapted from src/pkg/strconv/quote.go.
  298. func unhex(b byte) (v byte, ok bool) {
  299. switch {
  300. case '0' <= b && b <= '9':
  301. return b - '0', true
  302. case 'a' <= b && b <= 'f':
  303. return b - 'a' + 10, true
  304. case 'A' <= b && b <= 'F':
  305. return b - 'A' + 10, true
  306. }
  307. return 0, false
  308. }
  309. // Back off the parser by one token. Can only be done between calls to next().
  310. // It makes the next advance() a no-op.
  311. func (p *textParser) back() { p.backed = true }
  312. // Advances the parser and returns the new current token.
  313. func (p *textParser) next() *token {
  314. if p.backed || p.done {
  315. p.backed = false
  316. return &p.cur
  317. }
  318. p.advance()
  319. if p.done {
  320. p.cur.value = ""
  321. } else if len(p.cur.value) > 0 && p.cur.value[0] == '"' {
  322. // Look for multiple quoted strings separated by whitespace,
  323. // and concatenate them.
  324. cat := p.cur
  325. for {
  326. p.skipWhitespace()
  327. if p.done || p.s[0] != '"' {
  328. break
  329. }
  330. p.advance()
  331. if p.cur.err != nil {
  332. return &p.cur
  333. }
  334. cat.value += " " + p.cur.value
  335. cat.unquoted += p.cur.unquoted
  336. }
  337. p.done = false // parser may have seen EOF, but we want to return cat
  338. p.cur = cat
  339. }
  340. return &p.cur
  341. }
  342. // Return an error indicating which required field was not set.
  343. func (p *textParser) missingRequiredFieldError(sv reflect.Value) *ParseError {
  344. st := sv.Type()
  345. sprops := GetProperties(st)
  346. for i := 0; i < st.NumField(); i++ {
  347. if !isNil(sv.Field(i)) {
  348. continue
  349. }
  350. props := sprops.Prop[i]
  351. if props.Required {
  352. return p.errorf("message %v missing required field %q", st, props.OrigName)
  353. }
  354. }
  355. return p.errorf("message %v missing required field", st) // should not happen
  356. }
  357. // Returns the index in the struct for the named field, as well as the parsed tag properties.
  358. func structFieldByName(st reflect.Type, name string) (int, *Properties, bool) {
  359. sprops := GetProperties(st)
  360. i, ok := sprops.decoderOrigNames[name]
  361. if ok {
  362. return i, sprops.Prop[i], true
  363. }
  364. return -1, nil, false
  365. }
  366. // Consume a ':' from the input stream (if the next token is a colon),
  367. // returning an error if a colon is needed but not present.
  368. func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
  369. tok := p.next()
  370. if tok.err != nil {
  371. return tok.err
  372. }
  373. if tok.value != ":" {
  374. // Colon is optional when the field is a group or message.
  375. needColon := true
  376. switch props.Wire {
  377. case "group":
  378. needColon = false
  379. case "bytes":
  380. // A "bytes" field is either a message, a string, or a repeated field;
  381. // those three become *T, *string and []T respectively, so we can check for
  382. // this field being a pointer to a non-string.
  383. if typ.Kind() == reflect.Ptr {
  384. // *T or *string
  385. if typ.Elem().Kind() == reflect.String {
  386. break
  387. }
  388. } else if typ.Kind() == reflect.Slice {
  389. // []T or []*T
  390. if typ.Elem().Kind() != reflect.Ptr {
  391. break
  392. }
  393. }
  394. needColon = false
  395. }
  396. if needColon {
  397. return p.errorf("expected ':', found %q", tok.value)
  398. }
  399. p.back()
  400. }
  401. return nil
  402. }
  403. func (p *textParser) readStruct(sv reflect.Value, terminator string) *ParseError {
  404. st := sv.Type()
  405. reqCount := GetProperties(st).reqCount
  406. // A struct is a sequence of "name: value", terminated by one of
  407. // '>' or '}', or the end of the input. A name may also be
  408. // "[extension]".
  409. for {
  410. tok := p.next()
  411. if tok.err != nil {
  412. return tok.err
  413. }
  414. if tok.value == terminator {
  415. break
  416. }
  417. if tok.value == "[" {
  418. // Looks like an extension.
  419. //
  420. // TODO: Check whether we need to handle
  421. // namespace rooted names (e.g. ".something.Foo").
  422. tok = p.next()
  423. if tok.err != nil {
  424. return tok.err
  425. }
  426. var desc *ExtensionDesc
  427. // This could be faster, but it's functional.
  428. // TODO: Do something smarter than a linear scan.
  429. for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
  430. if d.Name == tok.value {
  431. desc = d
  432. break
  433. }
  434. }
  435. if desc == nil {
  436. return p.errorf("unrecognized extension %q", tok.value)
  437. }
  438. // Check the extension terminator.
  439. tok = p.next()
  440. if tok.err != nil {
  441. return tok.err
  442. }
  443. if tok.value != "]" {
  444. return p.errorf("unrecognized extension terminator %q", tok.value)
  445. }
  446. props := &Properties{}
  447. props.Parse(desc.Tag)
  448. typ := reflect.TypeOf(desc.ExtensionType)
  449. if err := p.checkForColon(props, typ); err != nil {
  450. return err
  451. }
  452. rep := desc.repeated()
  453. // Read the extension structure, and set it in
  454. // the value we're constructing.
  455. var ext reflect.Value
  456. if !rep {
  457. ext = reflect.New(typ).Elem()
  458. } else {
  459. ext = reflect.New(typ.Elem()).Elem()
  460. }
  461. if err := p.readAny(ext, props); err != nil {
  462. return err
  463. }
  464. ep := sv.Addr().Interface().(extendableProto)
  465. if !rep {
  466. SetExtension(ep, desc, ext.Interface())
  467. } else {
  468. old, err := GetExtension(ep, desc)
  469. var sl reflect.Value
  470. if err == nil {
  471. sl = reflect.ValueOf(old) // existing slice
  472. } else {
  473. sl = reflect.MakeSlice(typ, 0, 1)
  474. }
  475. sl = reflect.Append(sl, ext)
  476. SetExtension(ep, desc, sl.Interface())
  477. }
  478. } else {
  479. // This is a normal, non-extension field.
  480. fi, props, ok := structFieldByName(st, tok.value)
  481. if !ok {
  482. return p.errorf("unknown field name %q in %v", tok.value, st)
  483. }
  484. dst := sv.Field(fi)
  485. isDstNil := isNil(dst)
  486. // Check that it's not already set if it's not a repeated field.
  487. if !props.Repeated && !isDstNil && dst.Kind() == reflect.Ptr {
  488. return p.errorf("non-repeated field %q was repeated", tok.value)
  489. }
  490. if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
  491. return err
  492. }
  493. // Parse into the field.
  494. if err := p.readAny(dst, props); err != nil {
  495. return err
  496. }
  497. if props.Required {
  498. reqCount--
  499. }
  500. }
  501. // For backward compatibility, permit a semicolon or comma after a field.
  502. tok = p.next()
  503. if tok.err != nil {
  504. return tok.err
  505. }
  506. if tok.value != ";" && tok.value != "," {
  507. p.back()
  508. }
  509. }
  510. if reqCount > 0 {
  511. return p.missingRequiredFieldError(sv)
  512. }
  513. return nil
  514. }
  515. func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
  516. tok := p.next()
  517. if tok.err != nil {
  518. return tok.err
  519. }
  520. if tok.value == "" {
  521. return p.errorf("unexpected EOF")
  522. }
  523. if len(props.CustomType) > 0 {
  524. if props.Repeated {
  525. t := reflect.TypeOf(v.Interface())
  526. if t.Kind() == reflect.Slice {
  527. tc := reflect.TypeOf(new(Marshaler))
  528. ok := t.Elem().Implements(tc.Elem())
  529. if ok {
  530. fv := v
  531. flen := fv.Len()
  532. if flen == fv.Cap() {
  533. nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1)
  534. reflect.Copy(nav, fv)
  535. fv.Set(nav)
  536. }
  537. fv.SetLen(flen + 1)
  538. // Read one.
  539. p.back()
  540. return p.readAny(fv.Index(flen), props)
  541. }
  542. }
  543. }
  544. if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {
  545. custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler)
  546. err := custom.Unmarshal([]byte(tok.unquoted))
  547. if err != nil {
  548. return p.errorf("%v %v: %v", err, v.Type(), tok.value)
  549. }
  550. v.Set(reflect.ValueOf(custom))
  551. } else {
  552. custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler)
  553. err := custom.Unmarshal([]byte(tok.unquoted))
  554. if err != nil {
  555. return p.errorf("%v %v: %v", err, v.Type(), tok.value)
  556. }
  557. v.Set(reflect.Indirect(reflect.ValueOf(custom)))
  558. }
  559. return nil
  560. }
  561. switch fv := v; fv.Kind() {
  562. case reflect.Slice:
  563. at := v.Type()
  564. if at.Elem().Kind() == reflect.Uint8 {
  565. // Special case for []byte
  566. if tok.value[0] != '"' && tok.value[0] != '\'' {
  567. // Deliberately written out here, as the error after
  568. // this switch statement would write "invalid []byte: ...",
  569. // which is not as user-friendly.
  570. return p.errorf("invalid string: %v", tok.value)
  571. }
  572. bytes := []byte(tok.unquoted)
  573. fv.Set(reflect.ValueOf(bytes))
  574. return nil
  575. }
  576. // Repeated field. May already exist.
  577. flen := fv.Len()
  578. if flen == fv.Cap() {
  579. nav := reflect.MakeSlice(at, flen, 2*flen+1)
  580. reflect.Copy(nav, fv)
  581. fv.Set(nav)
  582. }
  583. fv.SetLen(flen + 1)
  584. // Read one.
  585. p.back()
  586. return p.readAny(fv.Index(flen), props)
  587. case reflect.Bool:
  588. // Either "true", "false", 1 or 0.
  589. switch tok.value {
  590. case "true", "1":
  591. fv.SetBool(true)
  592. return nil
  593. case "false", "0":
  594. fv.SetBool(false)
  595. return nil
  596. }
  597. case reflect.Float32, reflect.Float64:
  598. v := tok.value
  599. // Ignore 'f' for compatibility with output generated by C++, but don't
  600. // remove 'f' when the value is "-inf" or "inf".
  601. if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
  602. v = v[:len(v)-1]
  603. }
  604. if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
  605. fv.SetFloat(f)
  606. return nil
  607. }
  608. case reflect.Int32:
  609. if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
  610. fv.SetInt(x)
  611. return nil
  612. }
  613. if len(props.Enum) == 0 {
  614. break
  615. }
  616. m, ok := enumValueMaps[props.Enum]
  617. if !ok {
  618. break
  619. }
  620. x, ok := m[tok.value]
  621. if !ok {
  622. break
  623. }
  624. fv.SetInt(int64(x))
  625. return nil
  626. case reflect.Int64:
  627. if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
  628. fv.SetInt(x)
  629. return nil
  630. }
  631. case reflect.Ptr:
  632. // A basic field (indirected through pointer), or a repeated message/group
  633. p.back()
  634. fv.Set(reflect.New(fv.Type().Elem()))
  635. return p.readAny(fv.Elem(), props)
  636. case reflect.String:
  637. if tok.value[0] == '"' || tok.value[0] == '\'' {
  638. fv.SetString(tok.unquoted)
  639. return nil
  640. }
  641. case reflect.Struct:
  642. var terminator string
  643. switch tok.value {
  644. case "{":
  645. terminator = "}"
  646. case "<":
  647. terminator = ">"
  648. default:
  649. return p.errorf("expected '{' or '<', found %q", tok.value)
  650. }
  651. // TODO: Handle nested messages which implement textUnmarshaler.
  652. return p.readStruct(fv, terminator)
  653. case reflect.Uint32:
  654. if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
  655. fv.SetUint(uint64(x))
  656. return nil
  657. }
  658. case reflect.Uint64:
  659. if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
  660. fv.SetUint(x)
  661. return nil
  662. }
  663. }
  664. return p.errorf("invalid %v: %v", v.Type(), tok.value)
  665. }
  666. // UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
  667. // before starting to unmarshal, so any existing data in pb is always removed.
  668. func UnmarshalText(s string, pb Message) error {
  669. if um, ok := pb.(textUnmarshaler); ok {
  670. err := um.UnmarshalText([]byte(s))
  671. return err
  672. }
  673. pb.Reset()
  674. v := reflect.ValueOf(pb)
  675. if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
  676. return pe
  677. }
  678. return nil
  679. }