aboutsummaryrefslogtreecommitdiff
path: root/proto/text_parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'proto/text_parser.go')
-rw-r--r--proto/text_parser.go12
1 files changed, 12 insertions, 0 deletions
diff --git a/proto/text_parser.go b/proto/text_parser.go
index 13827f6..4d4167c 100644
--- a/proto/text_parser.go
+++ b/proto/text_parser.go
@@ -43,6 +43,13 @@ import (
"unicode/utf8"
)
+// textUnmarshaler is implemented by Messages that can unmarshal themsleves.
+// It is identical to encoding.TextUnmarshaler, introduced in go 1.2,
+// which will eventually replace it.
+type textUnmarshaler interface {
+ UnmarshalText(text []byte) error
+}
+
type ParseError struct {
Message string
Line int // 1-based line number
@@ -643,6 +650,7 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
default:
return p.errorf("expected '{' or '<', found %q", tok.value)
}
+ // TODO: Handle nested messages which implement textUnmarshaler.
return p.readStruct(fv, terminator)
case reflect.Uint32:
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
@@ -661,6 +669,10 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) *ParseError {
// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
// before starting to unmarshal, so any existing data in pb is always removed.
func UnmarshalText(s string, pb Message) error {
+ if um, ok := pb.(textUnmarshaler); ok {
+ err := um.UnmarshalText([]byte(s))
+ return err
+ }
pb.Reset()
v := reflect.ValueOf(pb)
if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {