reflect: support for struct tag use by multiple packages

Each package using struct field tags assumes that
it is the only package storing data in the tag.
This CL adds support in package reflect for sharing
tags between multiple packages.  In this scheme, the
tags must be of the form

        key:"value" key2:"value2"

(raw strings help when writing that tag in Go source).

reflect.StructField's Tag field now has type StructTag
(a string type), which has method Get(key string) string
that returns the associated value.

Clients of json and xml will need to be updated.
Code that says

        type T struct {
                X int "name"
        }

should become

        type T struct {
                X int `json:"name"`  // or `xml:"name"`
        }

Use govet to identify struct tags that need to be changed
to use the new syntax.

R=r, r, dsymonds, bradfitz, kevlar, fvbommel, n13m3y3r
CC=golang-dev
https://golang.org/cl/4645069
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go
index 94b0fb5..34d74b3 100644
--- a/src/pkg/reflect/all_test.go
+++ b/src/pkg/reflect/all_test.go
@@ -127,17 +127,17 @@
 	},
 	{struct {
 		x struct {
-			a int8 "hi there"
+			a int8 `reflect:"hi there"`
 		}
 	}{},
-		`struct { a int8 "hi there" }`,
+		`struct { a int8 "reflect:\"hi there\"" }`,
 	},
 	{struct {
 		x struct {
-			a int8 "hi \x00there\t\n\"\\"
+			a int8 `reflect:"hi \x00there\t\n\"\\"`
 		}
 	}{},
-		`struct { a int8 "hi \x00there\t\n\"\\" }`,
+		`struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
 	},
 	{struct {
 		x struct {
@@ -423,7 +423,7 @@
 
 	// make sure tag strings are not part of element type
 	typ = TypeOf(struct {
-		d []uint32 "TAG"
+		d []uint32 `reflect:"TAG"`
 	}{}).Field(0).Type
 	testType(t, 14, typ, "[]uint32")
 }
@@ -1544,3 +1544,23 @@
 		t.Errorf("after Fprintf CallSlice: %q != %q", b.String(), "hello 42 world")
 	}
 }
+
+var tagGetTests = []struct {
+	Tag   StructTag
+	Key   string
+	Value string
+}{
+	{`protobuf:"PB(1,2)"`, `protobuf`, `PB(1,2)`},
+	{`protobuf:"PB(1,2)"`, `foo`, ``},
+	{`protobuf:"PB(1,2)"`, `rotobuf`, ``},
+	{`protobuf:"PB(1,2)" json:"name"`, `json`, `name`},
+	{`protobuf:"PB(1,2)" json:"name"`, `protobuf`, `PB(1,2)`},
+}
+
+func TestTagGet(t *testing.T) {
+	for _, tt := range tagGetTests {
+		if v := tt.Tag.Get(tt.Key); v != tt.Value {
+			t.Errorf("StructTag(%#q).Get(%#q) = %#q, want %#q", tt.Tag, tt.Key, v, tt.Value)
+		}
+	}
+}