...

Source file src/github.com/gogo/protobuf/proto/text_parser.go

Documentation: github.com/gogo/protobuf/proto

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

View as plain text