jsonpb: Fix handling of repeated enums.

Enums used in maps is still broken, but commented-out test data
is now there, together with TODOs.

Fixes #164.
diff --git a/jsonpb/jsonpb.go b/jsonpb/jsonpb.go
index c4094ac..69ed7fd 100644
--- a/jsonpb/jsonpb.go
+++ b/jsonpb/jsonpb.go
@@ -436,7 +436,7 @@
 	if err := dec.Decode(&inputValue); err != nil {
 		return err
 	}
-	return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue)
+	return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil)
 }
 
 // Unmarshal unmarshals a JSON object stream into a protocol
@@ -455,13 +455,14 @@
 }
 
 // unmarshalValue converts/copies a value into the target.
-func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
+// prop may be nil.
+func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error {
 	targetType := target.Type()
 
 	// Allocate memory for pointer fields.
 	if targetType.Kind() == reflect.Ptr {
 		target.Set(reflect.New(targetType.Elem()))
-		return unmarshalValue(target.Elem(), inputValue)
+		return unmarshalValue(target.Elem(), inputValue, prop)
 	}
 
 	// Handle well-known types.
@@ -476,7 +477,7 @@
 			//  as the wrapped primitive type, except that null is allowed."
 			// encoding/json will turn JSON `null` into Go `nil`,
 			// so we don't have to do any extra work.
-			return unmarshalValue(target.Field(0), inputValue)
+			return unmarshalValue(target.Field(0), inputValue, prop)
 		case "Duration":
 			unq, err := strconv.Unquote(string(inputValue))
 			if err != nil {
@@ -510,6 +511,27 @@
 		}
 	}
 
+	// Handle enums, which have an underlying type of int32,
+	// and may appear as strings.
+	// The case of an enum appearing as a number is handled
+	// at the bottom of this function.
+	if inputValue[0] == '"' && prop != nil && prop.Enum != "" {
+		vmap := proto.EnumValueMap(prop.Enum)
+		// Don't need to do unquoting; valid enum names
+		// are from a limited character set.
+		s := inputValue[1 : len(inputValue)-1]
+		n, ok := vmap[string(s)]
+		if !ok {
+			return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum)
+		}
+		if target.Kind() == reflect.Ptr { // proto2
+			target.Set(reflect.New(targetType.Elem()))
+			target = target.Elem()
+		}
+		target.SetInt(int64(n))
+		return nil
+	}
+
 	// Handle nested messages.
 	if targetType.Kind() == reflect.Struct {
 		var jsonFields map[string]json.RawMessage
@@ -551,30 +573,7 @@
 				continue
 			}
 
-			// Handle enums, which have an underlying type of int32,
-			// and may appear as strings. We do this while handling
-			// the struct so we have access to the enum info.
-			// The case of an enum appearing as a number is handled
-			// by the recursive call to unmarshalValue.
-			if enum := sprops.Prop[i].Enum; valueForField[0] == '"' && enum != "" {
-				vmap := proto.EnumValueMap(enum)
-				// Don't need to do unquoting; valid enum names
-				// are from a limited character set.
-				s := valueForField[1 : len(valueForField)-1]
-				n, ok := vmap[string(s)]
-				if !ok {
-					return fmt.Errorf("unknown value %q for enum %s", s, enum)
-				}
-				f := target.Field(i)
-				if f.Kind() == reflect.Ptr { // proto2
-					f.Set(reflect.New(f.Type().Elem()))
-					f = f.Elem()
-				}
-				f.SetInt(int64(n))
-				continue
-			}
-
-			if err := unmarshalValue(target.Field(i), valueForField); err != nil {
+			if err := unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil {
 				return err
 			}
 		}
@@ -587,7 +586,7 @@
 				}
 				nv := reflect.New(oop.Type.Elem())
 				target.Field(oop.Field).Set(nv)
-				if err := unmarshalValue(nv.Elem().Field(0), raw); err != nil {
+				if err := unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil {
 					return err
 				}
 			}
@@ -613,7 +612,7 @@
 		len := len(slc)
 		target.Set(reflect.MakeSlice(targetType, len, len))
 		for i := 0; i < len; i++ {
-			if err := unmarshalValue(target.Index(i), slc[i]); err != nil {
+			if err := unmarshalValue(target.Index(i), slc[i], prop); err != nil {
 				return err
 			}
 		}
@@ -627,6 +626,13 @@
 			return err
 		}
 		target.Set(reflect.MakeMap(targetType))
+		var keyprop, valprop *proto.Properties
+		if prop != nil {
+			// These could still be nil if the protobuf metadata is broken somehow.
+			// TODO: This won't work because the fields are unexported.
+			// We should probably just reparse them.
+			//keyprop, valprop = prop.mkeyprop, prop.mvalprop
+		}
 		for ks, raw := range mp {
 			// Unmarshal map key. The core json library already decoded the key into a
 			// string, so we handle that specially. Other types were quoted post-serialization.
@@ -635,14 +641,14 @@
 				k = reflect.ValueOf(ks)
 			} else {
 				k = reflect.New(targetType.Key()).Elem()
-				if err := unmarshalValue(k, json.RawMessage(ks)); err != nil {
+				if err := unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil {
 					return err
 				}
 			}
 
 			// Unmarshal map value.
 			v := reflect.New(targetType.Elem()).Elem()
-			if err := unmarshalValue(v, raw); err != nil {
+			if err := unmarshalValue(v, raw, valprop); err != nil {
 				return err
 			}
 			target.SetMapIndex(k, v)