Consume a ':' from the input stream (if the next token is a colon), returning an error if a colon is needed but not present.
(props *Properties, typ reflect.Type)
| 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() |
no test coverage detected