all: refactor extensions, add proto.GetExtension etc.

Change protoiface.ExtensionDescV1 to implement protoreflect.ExtensionType.

ExtensionDescV1's Name field conflicts with the Descriptor Name method,
so change the protoreflect.{Message,Enum,Extension}Type types to no
longer implement the corresponding Descriptor interface. This also leads
to a clearer distinction between the two types.

Introduce a protoreflect.ExtensionTypeDescriptor type which bridges
between ExtensionType and ExtensionDescriptor.

Add extension accessor functions to the proto package:
proto.{Has,Clear,Get,Set}Extension. These functions take a
protoreflect.ExtensionType parameter, which allows writing the
same function call using either the old or new API:

  proto.GetExtension(message, somepb.E_ExtensionFoo)

Fixes golang/protobuf#908

Change-Id: Ibc65d12a46666297849114fd3aefbc4a597d9f08
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/189199
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/encoding/protojson/decode.go b/encoding/protojson/decode.go
index 7c0da23..1d22d3a 100644
--- a/encoding/protojson/decode.go
+++ b/encoding/protojson/decode.go
@@ -182,7 +182,9 @@
 			if err != nil && err != protoregistry.NotFound {
 				return errors.New("unable to resolve [%v]: %v", extName, err)
 			}
-			fd = extType
+			if extType != nil {
+				fd = extType.Descriptor()
+			}
 		} else {
 			// The name can either be the JSON name or the proto field name.
 			fd = fieldDescs.ByJSONName(name)
diff --git a/encoding/protojson/decode_test.go b/encoding/protojson/decode_test.go
index 2385dc4..9c4f93e 100644
--- a/encoding/protojson/decode_test.go
+++ b/encoding/protojson/decode_test.go
@@ -1200,10 +1200,10 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_OptExtBool, true)
-			setExtension(m, pb2.E_OptExtString, "extension field")
-			setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -1225,9 +1225,9 @@
 }`,
 		wantMessage: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
-			setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
+			proto.SetExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -1250,10 +1250,10 @@
 }`,
 		wantMessage: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -1282,9 +1282,9 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -1323,13 +1323,13 @@
 }`,
 		wantMessage: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
 				OptString: proto.String("just a regular extension"),
 			})
 			return m
@@ -1345,7 +1345,7 @@
 }`,
 		wantMessage: func() proto.Message {
 			m := &pb2.FakeMessageSet{}
-			setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
 			return m
@@ -1371,7 +1371,7 @@
 }`,
 		wantMessage: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("another not a messageset extension"),
 			})
 			return m
@@ -2402,7 +2402,7 @@
 }`,
 		wantMessage: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
+			proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
 			return m
 		}(),
 	}, {
diff --git a/encoding/protojson/encode_test.go b/encoding/protojson/encode_test.go
index 2aa61dd..5cacf9e 100644
--- a/encoding/protojson/encode_test.go
+++ b/encoding/protojson/encode_test.go
@@ -16,7 +16,6 @@
 	pimpl "google.golang.org/protobuf/internal/impl"
 	"google.golang.org/protobuf/proto"
 	preg "google.golang.org/protobuf/reflect/protoregistry"
-	"google.golang.org/protobuf/runtime/protoiface"
 
 	"google.golang.org/protobuf/encoding/testprotos/pb2"
 	"google.golang.org/protobuf/encoding/testprotos/pb3"
@@ -29,11 +28,6 @@
 	"google.golang.org/protobuf/types/known/wrapperspb"
 )
 
-// TODO: Replace this with proto.SetExtension.
-func setExtension(m proto.Message, xd *protoiface.ExtensionDescV1, val interface{}) {
-	m.ProtoReflect().Set(xd.Type, xd.Type.ValueOf(val))
-}
-
 func TestMarshal(t *testing.T) {
 	tests := []struct {
 		desc    string
@@ -886,10 +880,10 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_OptExtBool, true)
-			setExtension(m, pb2.E_OptExtString, "extension field")
-			setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -915,9 +909,9 @@
 		desc: "extensions of repeated fields",
 		input: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
-			setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
+			proto.SetExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -950,10 +944,10 @@
 		desc: "extensions of non-repeated fields in another message",
 		input: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -980,9 +974,9 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -1018,13 +1012,13 @@
 		desc: "MessageSet",
 		input: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
 				OptString: proto.String("just a regular extension"),
 			})
 			return m
@@ -1045,7 +1039,7 @@
 		desc: "not real MessageSet 1",
 		input: func() proto.Message {
 			m := &pb2.FakeMessageSet{}
-			setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
 			return m
@@ -1060,7 +1054,7 @@
 		desc: "not real MessageSet 2",
 		input: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("another not a messageset extension"),
 			})
 			return m
diff --git a/encoding/protojson/well_known_types.go b/encoding/protojson/well_known_types.go
index e744536..77833d8 100644
--- a/encoding/protojson/well_known_types.go
+++ b/encoding/protojson/well_known_types.go
@@ -189,7 +189,7 @@
 	// If type of value has custom JSON encoding, marshal out a field "value"
 	// with corresponding custom JSON encoding of the embedded message as a
 	// field.
-	if isCustomType(emt.FullName()) {
+	if isCustomType(emt.Descriptor().FullName()) {
 		o.encoder.WriteName("value")
 		return o.marshalCustomType(em)
 	}
@@ -235,7 +235,7 @@
 
 	// Create new message for the embedded message type and unmarshal into it.
 	em := emt.New()
-	if isCustomType(emt.FullName()) {
+	if isCustomType(emt.Descriptor().FullName()) {
 		// If embedded message is a custom type, unmarshal the JSON "value" field
 		// into it.
 		if err := o.unmarshalAnyValue(em); err != nil {
diff --git a/encoding/prototext/decode.go b/encoding/prototext/decode.go
index 4f384a0..06388c8 100644
--- a/encoding/prototext/decode.go
+++ b/encoding/prototext/decode.go
@@ -126,7 +126,9 @@
 			if err != nil && err != protoregistry.NotFound {
 				return errors.New("unable to resolve [%v]: %v", extName, err)
 			}
-			fd = xt
+			if xt != nil {
+				fd = xt.Descriptor()
+			}
 		}
 
 		if fd == nil {
diff --git a/encoding/prototext/decode_test.go b/encoding/prototext/decode_test.go
index 20ce133..588d9ee 100644
--- a/encoding/prototext/decode_test.go
+++ b/encoding/prototext/decode_test.go
@@ -1171,10 +1171,10 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_OptExtBool, true)
-			setExtension(m, pb2.E_OptExtString, "extension field")
-			setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -1207,9 +1207,9 @@
 `,
 		wantMessage: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
-			setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
+			proto.SetExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -1231,10 +1231,10 @@
 `,
 		wantMessage: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -1269,9 +1269,9 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -1299,13 +1299,13 @@
 `,
 		wantMessage: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
 				OptString: proto.String("just a regular extension"),
 			})
 			return m
@@ -1321,7 +1321,7 @@
 `,
 		wantMessage: func() proto.Message {
 			m := &pb2.FakeMessageSet{}
-			setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
 			return m
@@ -1346,7 +1346,7 @@
 }`,
 		wantMessage: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("another not a messageset extension"),
 			})
 			return m
diff --git a/encoding/prototext/encode_test.go b/encoding/prototext/encode_test.go
index c29169b..493a229 100644
--- a/encoding/prototext/encode_test.go
+++ b/encoding/prototext/encode_test.go
@@ -16,7 +16,6 @@
 	pimpl "google.golang.org/protobuf/internal/impl"
 	"google.golang.org/protobuf/proto"
 	preg "google.golang.org/protobuf/reflect/protoregistry"
-	"google.golang.org/protobuf/runtime/protoiface"
 
 	"google.golang.org/protobuf/encoding/testprotos/pb2"
 	"google.golang.org/protobuf/encoding/testprotos/pb3"
@@ -28,11 +27,6 @@
 	detrand.Disable()
 }
 
-// TODO: Use proto.SetExtension when available.
-func setExtension(m proto.Message, xd *protoiface.ExtensionDescV1, val interface{}) {
-	m.ProtoReflect().Set(xd.Type, xd.Type.ValueOf(val))
-}
-
 func TestMarshal(t *testing.T) {
 	tests := []struct {
 		desc    string
@@ -905,10 +899,10 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_OptExtBool, true)
-			setExtension(m, pb2.E_OptExtString, "extension field")
-			setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -933,7 +927,7 @@
 		desc: "extension field contains invalid UTF-8",
 		input: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_OptExtString, "abc\xff")
+			proto.SetExtension(m, pb2.E_OptExtString, "abc\xff")
 			return m
 		}(),
 		wantErr: true,
@@ -941,10 +935,10 @@
 		desc: "extension partial returns error",
 		input: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
+			proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
 				OptString: proto.String("partial1"),
 			})
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtPartial, &pb2.PartialRequired{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtPartial, &pb2.PartialRequired{
 				OptString: proto.String("partial2"),
 			})
 			return m
@@ -962,7 +956,7 @@
 		mo:   prototext.MarshalOptions{AllowPartial: true},
 		input: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
+			proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
 				OptString: proto.String("partial1"),
 			})
 			return m
@@ -975,9 +969,9 @@
 		desc: "extensions of repeated fields",
 		input: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
-			setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
+			proto.SetExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -1003,10 +997,10 @@
 		desc: "extensions of non-repeated fields in another message",
 		input: func() proto.Message {
 			m := &pb2.Extensions{}
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
-			setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
 				OptString: proto.String("nested in an extension"),
 				OptNested: &pb2.Nested{
 					OptString: proto.String("another nested in an extension"),
@@ -1032,9 +1026,9 @@
 				OptBool:   proto.Bool(true),
 				OptInt32:  proto.Int32(42),
 			}
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
-			setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
+			proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
 				&pb2.Nested{OptString: proto.String("one")},
 				&pb2.Nested{OptString: proto.String("two")},
 				&pb2.Nested{OptString: proto.String("three")},
@@ -1063,13 +1057,13 @@
 		desc: "MessageSet",
 		input: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
-			setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
+			proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
 				OptString: proto.String("just a regular extension"),
 			})
 			return m
@@ -1089,7 +1083,7 @@
 		desc: "not real MessageSet 1",
 		input: func() proto.Message {
 			m := &pb2.FakeMessageSet{}
-			setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("not a messageset extension"),
 			})
 			return m
@@ -1103,7 +1097,7 @@
 		desc: "not real MessageSet 2",
 		input: func() proto.Message {
 			m := &pb2.MessageSet{}
-			setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
+			proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
 				OptString: proto.String("another not a messageset extension"),
 			})
 			return m