goprotobuf: GetExtension now returns a specific error when the requested extension is missing.

Also tidy up property parsing a little bit.

R=r
CC=golang-dev
http://codereview.appspot.com/5557044
diff --git a/proto/extensions.go b/proto/extensions.go
index d02cadc..9f840fa 100644
--- a/proto/extensions.go
+++ b/proto/extensions.go
@@ -41,6 +41,9 @@
 	"strconv"
 )
 
+// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
+var ErrMissingExtension = errors.New("proto: missing extension")
+
 // ExtensionRange represents a range of message extensions for a protocol buffer.
 // Used in code generated by the protocol compiler.
 type ExtensionRange struct {
@@ -153,7 +156,7 @@
 }
 
 // GetExtension parses and returns the given extension of pb.
-// If the extension is not present it returns (nil, nil).
+// If the extension is not present it returns ErrMissingExtension.
 func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
 	if err := checkExtensionTypes(pb, extension); err != nil {
 		return nil, err
@@ -161,7 +164,7 @@
 
 	e, ok := pb.ExtensionMap()[extension.Field]
 	if !ok {
-		return nil, nil // not an error
+		return nil, ErrMissingExtension
 	}
 	if e.value != nil {
 		// Already decoded. Check the descriptor, though.
diff --git a/proto/properties.go b/proto/properties.go
index 206bf1d..556c177 100644
--- a/proto/properties.go
+++ b/proto/properties.go
@@ -153,7 +153,7 @@
 
 // Parse populates p by parsing a string in the protobuf struct field tag style.
 func (p *Properties) Parse(s string) {
-	// "bytes,49,opt,def=hello!,name=foo"
+	// "bytes,49,opt,name=foo,def=hello!"
 	fields := strings.Split(s, ",") // breaks def=, but handled below.
 	if len(fields) < 2 {
 		fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
@@ -207,11 +207,11 @@
 			p.Repeated = true
 		case f == "packed":
 			p.Packed = true
-		case len(f) >= 5 && f[0:5] == "name=":
+		case strings.HasPrefix(f, "name="):
 			p.OrigName = f[5:len(f)]
-		case len(f) >= 5 && f[0:5] == "enum=":
+		case strings.HasPrefix(f, "enum="):
 			p.Enum = f[5:len(f)]
-		case len(f) >= 4 && f[0:4] == "def=":
+		case strings.HasPrefix(f, "def="):
 			p.Default = f[4:len(f)] // rest of string
 			if i+1 < len(fields) {
 				// Commas aren't escaped, and def is always last.