goprotobuf: Miscellaneous fixes.
- Support single quoted strings.
- Allow declaring import path to hint at a package name.
R=r
CC=golang-dev
http://codereview.appspot.com/6366043
diff --git a/proto/text_parser.go b/proto/text_parser.go
index 7505805..8bacae5 100644
--- a/proto/text_parser.go
+++ b/proto/text_parser.go
@@ -155,17 +155,17 @@
case '<', '>', '{', '}', ':', '[', ']':
// Single symbol
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
- case '"':
+ case '"', '\'':
// Quoted string
i := 1
- for i < len(p.s) && p.s[i] != '"' && p.s[i] != '\n' {
+ for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
if p.s[i] == '\\' && i+1 < len(p.s) {
// skip escaped char
i++
}
i++
}
- if i >= len(p.s) || p.s[i] != '"' {
+ if i >= len(p.s) || p.s[i] != p.s[0] {
p.errorf("unmatched quote")
return
}
@@ -190,7 +190,30 @@
p.offset += len(p.cur.value)
}
+// quoteSwap returns a single quote for a double quote, and vice versa.
+// It is intended to be used with strings.Map.
+func quoteSwap(r rune) rune {
+ switch r {
+ case '\'':
+ return '"'
+ case '"':
+ return '\''
+ }
+ return r
+}
+
func unquoteC(s string) (string, error) {
+ // TODO: This is getting hacky. We should replace it work a self-contained parser.
+
+ // strconv.Unquote is for Go strings, but text format strings may use
+ // single *or* double quotes.
+ if s[0] == '\'' {
+ s = strings.Map(quoteSwap, s)
+ s, err := unquoteC(s)
+ s = strings.Map(quoteSwap, s)
+ return s, err
+ }
+
// A notable divergence between quoted string literals in Go
// and what is acceptable for text format protocol buffers:
// the former considers \' invalid, but the latter considers it valid.
@@ -424,7 +447,7 @@
at := v.Type()
if at.Elem().Kind() == reflect.Uint8 {
// Special case for []byte
- if tok.value[0] != '"' {
+ if tok.value[0] != '"' && tok.value[0] != '\'' {
// Deliberately written out here, as the error after
// this switch statement would write "invalid []byte: ...",
// which is not as user-friendly.
@@ -490,7 +513,7 @@
fv.Set(reflect.New(fv.Type().Elem()))
return p.readAny(fv.Elem(), props)
case reflect.String:
- if tok.value[0] == '"' {
+ if tok.value[0] == '"' || tok.value[0] == '\'' {
fv.SetString(tok.unquoted)
return nil
}