Просмотр исходного кода

Accept comma and semicolon characters in text format maps.

This makes this consistent with the C++ parser and structs in general.
David Symonds 10 лет назад
Родитель
Сommit
056d5ce64f
2 измененных файлов с 23 добавлено и 8 удалено
  1. 22 7
      proto/text_parser.go
  2. 1 1
      proto/text_parser_test.go

+ 22 - 7
proto/text_parser.go

@@ -567,6 +567,9 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 				if err := p.readAny(key, props.mkeyprop); err != nil {
 					return err
 				}
+				if err := p.consumeOptionalSeparator(); err != nil {
+					return err
+				}
 				if err := p.consumeToken("value"); err != nil {
 					return err
 				}
@@ -576,6 +579,9 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 				if err := p.readAny(val, props.mvalprop); err != nil {
 					return err
 				}
+				if err := p.consumeOptionalSeparator(); err != nil {
+					return err
+				}
 				if err := p.consumeToken(terminator); err != nil {
 					return err
 				}
@@ -605,14 +611,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 			}
 		}
 
-		// For backward compatibility, permit a semicolon or comma after a field.
-		tok = p.next()
-		if tok.err != nil {
-			return tok.err
-		}
-		if tok.value != ";" && tok.value != "," {
-			p.back()
+		if err := p.consumeOptionalSeparator(); err != nil {
+			return err
 		}
+
 	}
 
 	if reqCount > 0 {
@@ -621,6 +623,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 	return reqFieldErr
 }
 
+// consumeOptionalSeparator consumes an optional semicolon or comma.
+// It is used in readStruct to provide backward compatibility.
+func (p *textParser) consumeOptionalSeparator() error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != ";" && tok.value != "," {
+		p.back()
+	}
+	return nil
+}
+
 func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 	tok := p.next()
 	if tok.err != nil {

+ 1 - 1
proto/text_parser_test.go

@@ -462,7 +462,7 @@ func TestProto3TextParsing(t *testing.T) {
 func TestMapParsing(t *testing.T) {
 	m := new(MessageWithMap)
 	const in = `name_mapping:<key:1234 value:"Feist"> name_mapping:<key:1 value:"Beatles">` +
-		`msg_mapping:<key:-4 value:<f: 2.0>>` +
+		`msg_mapping:<key:-4, value:<f: 2.0>,>` + // separating commas are okay
 		`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
 		`byte_mapping:<key:true value:"so be it">`
 	want := &MessageWithMap{