encoding/textpb: add support for MessageSet

This only handles compliant MessageSet extension fields where the field
name has to be message_set_extension.

Current C++ lib allows for different message field names, which is a
possible bug as it makes marshal output possibly contain duplicate names
when more than one field extends the same MessageSet, and makes
unmarshaling confusing as to which field to populate.

Change-Id: Ifda828ba794fe7e058ee6004f03001b1031f6d1e
Reviewed-on: https://go-review.googlesource.com/c/156758
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/textpb/decode.go b/encoding/textpb/decode.go
index f421eab..aef9d40 100644
--- a/encoding/textpb/decode.go
+++ b/encoding/textpb/decode.go
@@ -129,7 +129,7 @@
 			xt := xtTypes.ByName(xtName)
 			if xt == nil {
 				var err error
-				xt, err = o.Resolver.FindExtensionByName(xtName)
+				xt, err = o.findExtension(xtName)
 				if err != nil && err != protoregistry.NotFound {
 					return errors.New("unable to resolve [%v]: %v", xtName, err)
 				}
@@ -183,6 +183,21 @@
 	return nerr.E
 }
 
+// findExtension returns protoreflect.ExtensionType from the Resolver if found.
+func (o UnmarshalOptions) findExtension(xtName pref.FullName) (pref.ExtensionType, error) {
+	xt, err := o.Resolver.FindExtensionByName(xtName)
+	if err == nil {
+		return xt, nil
+	}
+
+	// Check if this is a MessageSet extension field.
+	xt, err = o.Resolver.FindExtensionByName(xtName + ".message_set_extension")
+	if err == nil && isMessageSetExtension(xt) {
+		return xt, nil
+	}
+	return nil, protoregistry.NotFound
+}
+
 // unmarshalSingular unmarshals given text.Value into the non-repeated field.
 func (o UnmarshalOptions) unmarshalSingular(input text.Value, fd pref.FieldDescriptor, knownFields pref.KnownFields) error {
 	num := fd.Number()
diff --git a/encoding/textpb/decode_test.go b/encoding/textpb/decode_test.go
index 90a9e78..fa9c5a3 100644
--- a/encoding/textpb/decode_test.go
+++ b/encoding/textpb/decode_test.go
@@ -26,6 +26,7 @@
 )
 
 func init() {
+	// TODO: remove this when generated code registers to V2 global registry.
 	registerExtension(pb2.E_OptExtBool)
 	registerExtension(pb2.E_OptExtString)
 	registerExtension(pb2.E_OptExtEnum)
@@ -40,6 +41,11 @@
 	registerExtension(pb2.E_ExtensionsContainer_RptExtString)
 	registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
 	registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
+	registerExtension(pb2.E_MessageSetExtension)
+	registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
+	registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
+	registerExtension(pb2.E_MessageSetExtension_ExtNested)
+	registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
 }
 
 func registerExtension(xd *protoapi.ExtensionDesc) {
@@ -511,6 +517,20 @@
 			},
 		},
 	}, {
+		desc:         "oneof field set to last value",
+		inputMessage: &pb2.Oneofs{},
+		inputText: `
+msg: {
+  opt_string: "nested message"
+}
+str: "wins"
+`,
+		wantMessage: &pb2.Oneofs{
+			Union: &pb2.Oneofs_Str{
+				Str: "wins",
+			},
+		},
+	}, {
 		desc:         "repeated scalar using same field name",
 		inputMessage: &pb2.Repeats{},
 		inputText: `
@@ -1125,6 +1145,72 @@
 		inputText:    "[pb2.invalid_message_field]: true",
 		wantErr:      true,
 	}, {
+		desc:         "MessageSet",
+		inputMessage: &pb2.MessageSet{},
+		inputText: `
+[pb2.MessageSetExtension]: {
+  opt_string: "a messageset extension"
+}
+[pb2.MessageSetExtension.ext_nested]: {
+  opt_string: "just a regular extension"
+}
+[pb2.MessageSetExtension.not_message_set_extension]: {
+  opt_string: "not a messageset extension"
+}
+`,
+		wantMessage: func() proto.Message {
+			m := &pb2.MessageSet{}
+			setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
+				OptString: scalar.String("a messageset extension"),
+			})
+			setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
+				OptString: scalar.String("not a messageset extension"),
+			})
+			setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
+				OptString: scalar.String("just a regular extension"),
+			})
+			return m
+		}(),
+	}, {
+		desc:         "not real MessageSet 1",
+		inputMessage: &pb2.FakeMessageSet{},
+		inputText: `
+[pb2.FakeMessageSetExtension.message_set_extension]: {
+  opt_string: "not a messageset extension"
+}
+`,
+		wantMessage: func() proto.Message {
+			m := &pb2.FakeMessageSet{}
+			setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
+				OptString: scalar.String("not a messageset extension"),
+			})
+			return m
+		}(),
+	}, {
+		desc:         "not real MessageSet 2",
+		inputMessage: &pb2.FakeMessageSet{},
+		inputText: `
+[pb2.FakeMessageSetExtension]: {
+  opt_string: "not a messageset extension"
+}
+`,
+		wantErr: true,
+	}, {
+		desc:         "not real MessageSet 3",
+		inputMessage: &pb2.MessageSet{},
+		inputText: `
+[pb2.message_set_extension]: {
+  opt_string: "another not a messageset extension"
+}
+`,
+		wantMessage: func() proto.Message {
+			m := &pb2.MessageSet{}
+			setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
+				OptString: scalar.String("another not a messageset extension"),
+			})
+			return m
+		}(),
+	}, {
 		desc:         "Any not expanded",
 		inputMessage: &pb2.KnownTypes{},
 		inputText: `opt_any: {
diff --git a/encoding/textpb/encode.go b/encoding/textpb/encode.go
index 54f4f54..73326d1 100644
--- a/encoding/textpb/encode.go
+++ b/encoding/textpb/encode.go
@@ -15,6 +15,8 @@
 	"github.com/golang/protobuf/v2/proto"
 	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
 	"github.com/golang/protobuf/v2/reflect/protoregistry"
+
+	descpb "github.com/golang/protobuf/v2/types/descriptor"
 )
 
 // Marshal writes the given proto.Message in textproto format using default options.
@@ -302,14 +304,16 @@
 
 	var err error
 	xtTypes.Range(func(xt pref.ExtensionType) bool {
-		// TODO: Handle MessageSet.  Field name should be message_set_extension
-		// of message type without any fields and has message option
-		// message_set_wire_format=true.
+		name := xt.FullName()
+		// If extended type is a MessageSet, set field name to be the message type name.
+		if isMessageSetExtension(xt) {
+			name = xt.MessageType().FullName()
+		}
 
 		num := xt.Number()
 		if knownFields.Has(num) {
 			// Use string type to produce [name] format.
-			tname := text.ValueOf(string(xt.FullName()))
+			tname := text.ValueOf(string(name))
 			pval := knownFields.Get(num)
 			xtFields, err = o.appendField(xtFields, tname, pval, xt)
 			if err != nil {
@@ -329,6 +333,29 @@
 	return append(msgFields, xtFields...), nerr.E
 }
 
+// isMessageSetExtension reports whether extension extends a message set.
+func isMessageSetExtension(xt pref.ExtensionType) bool {
+	if xt.Name() != "message_set_extension" {
+		return false
+	}
+	mt := xt.MessageType()
+	if mt == nil {
+		return false
+	}
+	if xt.FullName().Parent() != mt.FullName() {
+		return false
+	}
+	xmt := xt.ExtendedType()
+	if xmt.Fields().Len() != 0 {
+		return false
+	}
+	opt := xmt.Options().(*descpb.MessageOptions)
+	if opt == nil {
+		return false
+	}
+	return opt.GetMessageSetWireFormat()
+}
+
 // appendUnknown parses the given []byte and appends field(s) into the given fields slice.
 // This function assumes proper encoding in the given []byte.
 func appendUnknown(fields [][2]text.Value, b []byte) [][2]text.Value {
diff --git a/encoding/textpb/encode_test.go b/encoding/textpb/encode_test.go
index 9c79761..963fafe 100644
--- a/encoding/textpb/encode_test.go
+++ b/encoding/textpb/encode_test.go
@@ -959,33 +959,57 @@
 [pb2.ExtensionsContainer.rpt_ext_string]: "hello"
 [pb2.ExtensionsContainer.rpt_ext_string]: "world"
 `,
-		/* TODO: test for MessageSet
-		   	}, {
-		   		desc: "MessageSet",
-		   		input: func() proto.Message {
-		   			m := &pb2.MessageSet{}
-		   			setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
-		   				OptString: scalar.String("a messageset extension"),
-		   			})
-		   			setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
-		   				OptString: scalar.String("not a messageset extension"),
-		   			})
-		   			setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
-		   				OptString: scalar.String("just a regular extension"),
-		   			})
-		   			return m
-		   		}(),
-		   		want: `[pb2.MessageSetExtension]: {
-		     opt_string: "a messageset extension"
-		   }
-		   [pb2.MessageSetExtension.ext_nested]: {
-		     opt_string: "just a regular extension"
-		   }
-		   [pb2.MessageSetExtension.not_message_set_extension]: {
-		     opt_string: "not a messageset extension"
-		   }
-		   `,
-		*/
+	}, {
+		desc: "MessageSet",
+		input: func() proto.Message {
+			m := &pb2.MessageSet{}
+			setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
+				OptString: scalar.String("a messageset extension"),
+			})
+			setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
+				OptString: scalar.String("not a messageset extension"),
+			})
+			setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
+				OptString: scalar.String("just a regular extension"),
+			})
+			return m
+		}(),
+		want: `[pb2.MessageSetExtension]: {
+  opt_string: "a messageset extension"
+}
+[pb2.MessageSetExtension.ext_nested]: {
+  opt_string: "just a regular extension"
+}
+[pb2.MessageSetExtension.not_message_set_extension]: {
+  opt_string: "not a messageset extension"
+}
+`,
+	}, {
+		desc: "not real MessageSet 1",
+		input: func() proto.Message {
+			m := &pb2.FakeMessageSet{}
+			setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
+				OptString: scalar.String("not a messageset extension"),
+			})
+			return m
+		}(),
+		want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
+  opt_string: "not a messageset extension"
+}
+`,
+	}, {
+		desc: "not real MessageSet 2",
+		input: func() proto.Message {
+			m := &pb2.MessageSet{}
+			setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
+				OptString: scalar.String("another not a messageset extension"),
+			})
+			return m
+		}(),
+		want: `[pb2.message_set_extension]: {
+  opt_string: "another not a messageset extension"
+}
+`,
 	}, {
 		desc: "Any message not expanded",
 		mo: textpb.MarshalOptions{
diff --git a/encoding/textpb/testprotos/pb2/test.pb.go b/encoding/textpb/testprotos/pb2/test.pb.go
index 84eb603..57f7392 100644
--- a/encoding/textpb/testprotos/pb2/test.pb.go
+++ b/encoding/textpb/testprotos/pb2/test.pb.go
@@ -1201,6 +1201,91 @@
 	return ""
 }
 
+type FakeMessageSet struct {
+	XXX_NoUnkeyedLiteral         struct{} `json:"-"`
+	proto.XXX_InternalExtensions `json:"-"`
+	XXX_unrecognized             []byte `json:"-"`
+	XXX_sizecache                int32  `json:"-"`
+}
+
+func (m *FakeMessageSet) ProtoReflect() protoreflect.Message {
+	return xxx_Test_protoFile_messageTypes[15].MessageOf(m)
+}
+func (m *FakeMessageSet) Reset()         { *m = FakeMessageSet{} }
+func (m *FakeMessageSet) String() string { return proto.CompactTextString(m) }
+func (*FakeMessageSet) ProtoMessage()    {}
+func (*FakeMessageSet) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c8d7acc1bcec9a72_gzipped, []int{15}
+}
+
+var extRange_FakeMessageSet = []proto.ExtensionRange{
+	{Start: 4, End: 536870911},
+}
+
+func (*FakeMessageSet) ExtensionRangeArray() []proto.ExtensionRange {
+	return extRange_FakeMessageSet
+}
+
+func (m *FakeMessageSet) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FakeMessageSet.Unmarshal(m, b)
+}
+func (m *FakeMessageSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FakeMessageSet.Marshal(b, m, deterministic)
+}
+func (m *FakeMessageSet) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FakeMessageSet.Merge(m, src)
+}
+func (m *FakeMessageSet) XXX_Size() int {
+	return xxx_messageInfo_FakeMessageSet.Size(m)
+}
+func (m *FakeMessageSet) XXX_DiscardUnknown() {
+	xxx_messageInfo_FakeMessageSet.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FakeMessageSet proto.InternalMessageInfo
+
+type FakeMessageSetExtension struct {
+	OptString            *string  `protobuf:"bytes,1,opt,name=opt_string,json=optString" json:"opt_string,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *FakeMessageSetExtension) ProtoReflect() protoreflect.Message {
+	return xxx_Test_protoFile_messageTypes[16].MessageOf(m)
+}
+func (m *FakeMessageSetExtension) Reset()         { *m = FakeMessageSetExtension{} }
+func (m *FakeMessageSetExtension) String() string { return proto.CompactTextString(m) }
+func (*FakeMessageSetExtension) ProtoMessage()    {}
+func (*FakeMessageSetExtension) Descriptor() ([]byte, []int) {
+	return fileDescriptor_c8d7acc1bcec9a72_gzipped, []int{16}
+}
+
+func (m *FakeMessageSetExtension) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FakeMessageSetExtension.Unmarshal(m, b)
+}
+func (m *FakeMessageSetExtension) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FakeMessageSetExtension.Marshal(b, m, deterministic)
+}
+func (m *FakeMessageSetExtension) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FakeMessageSetExtension.Merge(m, src)
+}
+func (m *FakeMessageSetExtension) XXX_Size() int {
+	return xxx_messageInfo_FakeMessageSetExtension.Size(m)
+}
+func (m *FakeMessageSetExtension) XXX_DiscardUnknown() {
+	xxx_messageInfo_FakeMessageSetExtension.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FakeMessageSetExtension proto.InternalMessageInfo
+
+func (m *FakeMessageSetExtension) GetOptString() string {
+	if m != nil && m.OptString != nil {
+		return *m.OptString
+	}
+	return ""
+}
+
 // Message contains well-known type fields.
 type KnownTypes struct {
 	OptBool              *wrappers.BoolValue   `protobuf:"bytes,1,opt,name=opt_bool,json=optBool" json:"opt_bool,omitempty"`
@@ -1225,13 +1310,13 @@
 }
 
 func (m *KnownTypes) ProtoReflect() protoreflect.Message {
-	return xxx_Test_protoFile_messageTypes[15].MessageOf(m)
+	return xxx_Test_protoFile_messageTypes[17].MessageOf(m)
 }
 func (m *KnownTypes) Reset()         { *m = KnownTypes{} }
 func (m *KnownTypes) String() string { return proto.CompactTextString(m) }
 func (*KnownTypes) ProtoMessage()    {}
 func (*KnownTypes) Descriptor() ([]byte, []int) {
-	return fileDescriptor_c8d7acc1bcec9a72_gzipped, []int{15}
+	return fileDescriptor_c8d7acc1bcec9a72_gzipped, []int{17}
 }
 
 func (m *KnownTypes) XXX_Unmarshal(b []byte) error {
@@ -1375,7 +1460,7 @@
 }
 
 func (m *Nests_OptGroup) ProtoReflect() protoreflect.Message {
-	return xxx_Test_protoFile_messageTypes[16].MessageOf(m)
+	return xxx_Test_protoFile_messageTypes[18].MessageOf(m)
 }
 func (m *Nests_OptGroup) Reset()         { *m = Nests_OptGroup{} }
 func (m *Nests_OptGroup) String() string { return proto.CompactTextString(m) }
@@ -1438,7 +1523,7 @@
 }
 
 func (m *Nests_RptGroup) ProtoReflect() protoreflect.Message {
-	return xxx_Test_protoFile_messageTypes[17].MessageOf(m)
+	return xxx_Test_protoFile_messageTypes[19].MessageOf(m)
 }
 func (m *Nests_RptGroup) Reset()         { *m = Nests_RptGroup{} }
 func (m *Nests_RptGroup) String() string { return proto.CompactTextString(m) }
@@ -1480,7 +1565,7 @@
 }
 
 func (m *Nests_OptGroup_OptNestedGroup) ProtoReflect() protoreflect.Message {
-	return xxx_Test_protoFile_messageTypes[18].MessageOf(m)
+	return xxx_Test_protoFile_messageTypes[20].MessageOf(m)
 }
 func (m *Nests_OptGroup_OptNestedGroup) Reset()         { *m = Nests_OptGroup_OptNestedGroup{} }
 func (m *Nests_OptGroup_OptNestedGroup) String() string { return proto.CompactTextString(m) }
@@ -1577,6 +1662,15 @@
 	Filename:      "encoding/textpb/testprotos/pb2/test.proto",
 }
 
+var E_MessageSetExtension = &proto.ExtensionDesc{
+	ExtendedType:  (*MessageSet)(nil),
+	ExtensionType: (*FakeMessageSetExtension)(nil),
+	Field:         50,
+	Name:          "pb2.",
+	Tag:           "bytes,50,opt,name=message_set_extension",
+	Filename:      "encoding/textpb/testprotos/pb2/test.proto",
+}
+
 var E_ExtensionsContainer_OptExtBool = &proto.ExtensionDesc{
 	ExtendedType:  (*Extensions)(nil),
 	ExtensionType: (*bool)(nil),
@@ -1667,6 +1761,15 @@
 	Filename:      "encoding/textpb/testprotos/pb2/test.proto",
 }
 
+var E_FakeMessageSetExtension_MessageSetExtension = &proto.ExtensionDesc{
+	ExtendedType:  (*FakeMessageSet)(nil),
+	ExtensionType: (*FakeMessageSetExtension)(nil),
+	Field:         10,
+	Name:          "pb2.FakeMessageSetExtension.message_set_extension",
+	Tag:           "bytes,10,opt,name=message_set_extension",
+	Filename:      "encoding/textpb/testprotos/pb2/test.proto",
+}
+
 func init() {
 	proto.RegisterFile("encoding/textpb/testprotos/pb2/test.proto", fileDescriptor_c8d7acc1bcec9a72_gzipped)
 	proto.RegisterEnum("pb2.Enum", Enum_name, Enum_value)
@@ -1693,6 +1796,8 @@
 	proto.RegisterType((*ExtensionsContainer)(nil), "pb2.ExtensionsContainer")
 	proto.RegisterType((*MessageSet)(nil), "pb2.MessageSet")
 	proto.RegisterType((*MessageSetExtension)(nil), "pb2.MessageSetExtension")
+	proto.RegisterType((*FakeMessageSet)(nil), "pb2.FakeMessageSet")
+	proto.RegisterType((*FakeMessageSetExtension)(nil), "pb2.FakeMessageSetExtension")
 	proto.RegisterType((*KnownTypes)(nil), "pb2.KnownTypes")
 	proto.RegisterType((*Nests_OptGroup)(nil), "pb2.Nests.OptGroup")
 	proto.RegisterType((*Nests_RptGroup)(nil), "pb2.Nests.RptGroup")
@@ -1704,6 +1809,7 @@
 	proto.RegisterExtension(E_RptExtFixed32)
 	proto.RegisterExtension(E_RptExtEnum)
 	proto.RegisterExtension(E_RptExtNested)
+	proto.RegisterExtension(E_MessageSetExtension)
 	proto.RegisterExtension(E_ExtensionsContainer_OptExtBool)
 	proto.RegisterExtension(E_ExtensionsContainer_OptExtString)
 	proto.RegisterExtension(E_ExtensionsContainer_OptExtEnum)
@@ -1714,10 +1820,11 @@
 	proto.RegisterExtension(E_MessageSetExtension_MessageSetExtension)
 	proto.RegisterExtension(E_MessageSetExtension_NotMessageSetExtension)
 	proto.RegisterExtension(E_MessageSetExtension_ExtNested)
+	proto.RegisterExtension(E_FakeMessageSetExtension_MessageSetExtension)
 }
 
 var fileDescriptor_c8d7acc1bcec9a72 = []byte{
-	// 5909 bytes of the wire-encoded FileDescriptorProto
+	// 6198 bytes of the wire-encoded FileDescriptorProto
 	0x0a, 0x29, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x70,
 	0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x70, 0x62, 0x32,
 	0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x70, 0x62, 0x32,
@@ -1994,100 +2101,118 @@
 	0x6e, 0x32, 0x3b, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12,
 	0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74,
 	0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x4e, 0x65, 0x73,
-	0x74, 0x65, 0x64, 0x52, 0x09, 0x65, 0x78, 0x74, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x22, 0xa6,
-	0x07, 0x0a, 0x0a, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x35, 0x0a,
-	0x08, 0x6f, 0x70, 0x74, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
-	0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6f, 0x70, 0x74,
-	0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x33,
-	0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56,
-	0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x38,
-	0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08,
-	0x6f, 0x70, 0x74, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x3b, 0x0a, 0x0a, 0x6f, 0x70, 0x74, 0x5f,
-	0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67,
-	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55,
-	0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x55,
-	0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x3b, 0x0a, 0x0a, 0x6f, 0x70, 0x74, 0x5f, 0x75, 0x69, 0x6e,
-	0x74, 0x36, 0x34, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74,
-	0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x55, 0x69, 0x6e, 0x74,
-	0x36, 0x34, 0x12, 0x38, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18,
-	0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c,
-	0x75, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x3b, 0x0a, 0x0a,
-	0x6f, 0x70, 0x74, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09,
-	0x6f, 0x70, 0x74, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6f, 0x70, 0x74,
-	0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
+	0x74, 0x65, 0x64, 0x52, 0x09, 0x65, 0x78, 0x74, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x22, 0x1a,
+	0x0a, 0x0e, 0x46, 0x61, 0x6b, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74,
+	0x2a, 0x08, 0x08, 0x04, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9f, 0x01, 0x0a, 0x17, 0x46,
+	0x61, 0x6b, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x45, 0x78, 0x74,
+	0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x70, 0x74, 0x5f, 0x73, 0x74,
+	0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x53,
+	0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x65, 0x0a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x5f, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13,
+	0x2e, 0x70, 0x62, 0x32, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x53, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x62, 0x32, 0x2e,
+	0x46, 0x61, 0x6b, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x45, 0x78,
+	0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x53, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa6, 0x07, 0x0a,
+	0x0a, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x6f,
+	0x70, 0x74, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
 	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
-	0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x74,
-	0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x62, 0x79,
-	0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65,
-	0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73,
-	0x12, 0x3c, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f,
-	0x0a, 0x0d, 0x6f, 0x70, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18,
-	0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x52, 0x0c, 0x6f, 0x70, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
-	0x36, 0x0a, 0x0a, 0x6f, 0x70, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x18, 0x19, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x09, 0x6f, 0x70,
-	0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x5f, 0x6c,
-	0x69, 0x73, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74,
-	0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33,
-	0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x56, 0x61,
-	0x6c, 0x75, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79,
-	0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x08,
-	0x6f, 0x70, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x5f,
-	0x61, 0x6e, 0x79, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52,
-	0x06, 0x6f, 0x70, 0x74, 0x41, 0x6e, 0x79, 0x2a, 0x35, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12,
-	0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
-	0x46, 0x49, 0x52, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x43, 0x4f, 0x4e,
-	0x44, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x45, 0x4e, 0x54, 0x48, 0x10, 0x0a, 0x3a, 0x31,
-	0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x0f,
-	0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18,
-	0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6f, 0x70, 0x74, 0x45, 0x78, 0x74, 0x42, 0x6f, 0x6f,
-	0x6c, 0x3a, 0x35, 0x0a, 0x0e, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x74, 0x72,
-	0x69, 0x6e, 0x67, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x70, 0x74, 0x45,
-	0x78, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3c, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x5f,
-	0x65, 0x78, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45,
-	0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x09, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0a, 0x6f, 0x70, 0x74, 0x45,
-	0x78, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x42, 0x0a, 0x0e, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x78,
-	0x74, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45,
-	0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x0b, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x0c, 0x6f, 0x70,
-	0x74, 0x45, 0x78, 0x74, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x3a, 0x37, 0x0a, 0x0f, 0x72, 0x70,
-	0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x0f, 0x2e,
-	0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x1f,
-	0x20, 0x03, 0x28, 0x07, 0x52, 0x0d, 0x72, 0x70, 0x74, 0x45, 0x78, 0x74, 0x46, 0x69, 0x78, 0x65,
-	0x64, 0x33, 0x32, 0x3a, 0x3c, 0x0a, 0x0c, 0x72, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x65,
-	0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x20, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x32,
-	0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0a, 0x72, 0x70, 0x74, 0x45, 0x78, 0x74, 0x45, 0x6e, 0x75,
-	0x6d, 0x3a, 0x42, 0x0a, 0x0e, 0x72, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x6e, 0x65, 0x73,
-	0x74, 0x65, 0x64, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, 0x32,
-	0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x0c, 0x72, 0x70, 0x74, 0x45, 0x78, 0x74, 0x4e,
-	0x65, 0x73, 0x74, 0x65, 0x64, 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
-	0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2f, 0x76, 0x32, 0x2f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x2f,
-	0x74, 0x65, 0x78, 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x73, 0x2f, 0x70, 0x62, 0x32,
+	0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x42, 0x6f,
+	0x6f, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c,
+	0x75, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x38, 0x0a, 0x09,
+	0x6f, 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6f, 0x70,
+	0x74, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x3b, 0x0a, 0x0a, 0x6f, 0x70, 0x74, 0x5f, 0x75, 0x69,
+	0x6e, 0x74, 0x33, 0x32, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e,
+	0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x55, 0x69, 0x6e,
+	0x74, 0x33, 0x32, 0x12, 0x3b, 0x0a, 0x0a, 0x6f, 0x70, 0x74, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36,
+	0x34, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34,
+	0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34,
+	0x12, 0x38, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
+	0x52, 0x08, 0x6f, 0x70, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x6f, 0x70,
+	0x74, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x70,
+	0x74, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6f, 0x70, 0x74, 0x5f, 0x73,
+	0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
+	0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x53, 0x74,
+	0x72, 0x69, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65,
+	0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56,
+	0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3c,
+	0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x14,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x0b, 0x6f, 0x70, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x0d,
+	0x6f, 0x70, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x15, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
+	0x0c, 0x6f, 0x70, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x36, 0x0a,
+	0x0a, 0x6f, 0x70, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x53,
+	0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x5f, 0x6c, 0x69, 0x73,
+	0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61,
+	0x6c, 0x75, 0x65, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x09,
+	0x6f, 0x70, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x56, 0x61, 0x6c, 0x75,
+	0x65, 0x12, 0x33, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x1e,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x08, 0x6f, 0x70,
+	0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x5f, 0x61, 0x6e,
+	0x79, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x06, 0x6f,
+	0x70, 0x74, 0x41, 0x6e, 0x79, 0x2a, 0x35, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0b, 0x0a,
+	0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x49,
+	0x52, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x10,
+	0x02, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x45, 0x4e, 0x54, 0x48, 0x10, 0x0a, 0x3a, 0x31, 0x0a, 0x0c,
+	0x6f, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x0f, 0x2e, 0x70,
+	0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x15, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x0a, 0x6f, 0x70, 0x74, 0x45, 0x78, 0x74, 0x42, 0x6f, 0x6f, 0x6c, 0x3a,
+	0x35, 0x0a, 0x0e, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e,
+	0x67, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
+	0x6e, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x70, 0x74, 0x45, 0x78, 0x74,
+	0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x3c, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x78,
+	0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74,
+	0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e,
+	0x70, 0x62, 0x32, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x0a, 0x6f, 0x70, 0x74, 0x45, 0x78, 0x74,
+	0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x42, 0x0a, 0x0e, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f,
+	0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74,
+	0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
+	0x70, 0x62, 0x32, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x0c, 0x6f, 0x70, 0x74, 0x45,
+	0x78, 0x74, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x3a, 0x37, 0x0a, 0x0f, 0x72, 0x70, 0x74, 0x5f,
+	0x65, 0x78, 0x74, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x0f, 0x2e, 0x70, 0x62,
+	0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x1f, 0x20, 0x03,
+	0x28, 0x07, 0x52, 0x0d, 0x72, 0x70, 0x74, 0x45, 0x78, 0x74, 0x46, 0x69, 0x78, 0x65, 0x64, 0x33,
+	0x32, 0x3a, 0x3c, 0x0a, 0x0c, 0x72, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x65, 0x6e, 0x75,
+	0x6d, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
+	0x6e, 0x73, 0x18, 0x20, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45,
+	0x6e, 0x75, 0x6d, 0x52, 0x0a, 0x72, 0x70, 0x74, 0x45, 0x78, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x3a,
+	0x42, 0x0a, 0x0e, 0x72, 0x70, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x5f, 0x6e, 0x65, 0x73, 0x74, 0x65,
+	0x64, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
+	0x6e, 0x73, 0x18, 0x21, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x4e,
+	0x65, 0x73, 0x74, 0x65, 0x64, 0x52, 0x0c, 0x72, 0x70, 0x74, 0x45, 0x78, 0x74, 0x4e, 0x65, 0x73,
+	0x74, 0x65, 0x64, 0x3a, 0x61, 0x0a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73,
+	0x65, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x70,
+	0x62, 0x32, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x18, 0x32, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x62, 0x32, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x4d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
+	0x6e, 0x52, 0x13, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x45, 0x78, 0x74,
+	0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x32, 0x2f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67,
+	0x2f, 0x74, 0x65, 0x78, 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x73, 0x2f, 0x70, 0x62, 0x32,
 }
 
 var fileDescriptor_c8d7acc1bcec9a72_gzipped = func() []byte {
@@ -2103,7 +2228,7 @@
 var Test_protoFile protoreflect.FileDescriptor
 
 var xxx_Test_protoFile_enumTypes [2]protoreflect.EnumType
-var xxx_Test_protoFile_messageTypes [26]protoimpl.MessageType
+var xxx_Test_protoFile_messageTypes [28]protoimpl.MessageType
 var xxx_Test_protoFile_goTypes = []interface{}{
 	(Enum)(0),                             // 0: pb2.Enum
 	(Enums_NestedEnum)(0),                 // 1: pb2.Enums.NestedEnum
@@ -2122,33 +2247,35 @@
 	(*ExtensionsContainer)(nil),           // 14: pb2.ExtensionsContainer
 	(*MessageSet)(nil),                    // 15: pb2.MessageSet
 	(*MessageSetExtension)(nil),           // 16: pb2.MessageSetExtension
-	(*KnownTypes)(nil),                    // 17: pb2.KnownTypes
-	(*Nests_OptGroup)(nil),                // 18: pb2.Nests.OptGroup
-	(*Nests_RptGroup)(nil),                // 19: pb2.Nests.RptGroup
-	(*Nests_OptGroup_OptNestedGroup)(nil), // 20: pb2.Nests.OptGroup.OptNestedGroup
-	nil,                                   // 21: pb2.Maps.Int32ToStrEntry
-	nil,                                   // 22: pb2.Maps.Sfixed64ToBoolEntry
-	nil,                                   // 23: pb2.Maps.BoolToUint32Entry
-	nil,                                   // 24: pb2.Maps.Uint64ToEnumEntry
-	nil,                                   // 25: pb2.Maps.StrToNestedEntry
-	nil,                                   // 26: pb2.Maps.StrToOneofsEntry
-	nil,                                   // 27: pb2.IndirectRequired.StrToNestedEntry
-	(*wrappers.BoolValue)(nil),            // 28: google.protobuf.BoolValue
-	(*wrappers.Int32Value)(nil),           // 29: google.protobuf.Int32Value
-	(*wrappers.Int64Value)(nil),           // 30: google.protobuf.Int64Value
-	(*wrappers.UInt32Value)(nil),          // 31: google.protobuf.UInt32Value
-	(*wrappers.UInt64Value)(nil),          // 32: google.protobuf.UInt64Value
-	(*wrappers.FloatValue)(nil),           // 33: google.protobuf.FloatValue
-	(*wrappers.DoubleValue)(nil),          // 34: google.protobuf.DoubleValue
-	(*wrappers.StringValue)(nil),          // 35: google.protobuf.StringValue
-	(*wrappers.BytesValue)(nil),           // 36: google.protobuf.BytesValue
-	(*duration.Duration)(nil),             // 37: google.protobuf.Duration
-	(*timestamp.Timestamp)(nil),           // 38: google.protobuf.Timestamp
-	(*_struct.Struct)(nil),                // 39: google.protobuf.Struct
-	(*_struct.ListValue)(nil),             // 40: google.protobuf.ListValue
-	(*_struct.Value)(nil),                 // 41: google.protobuf.Value
-	(*empty.Empty)(nil),                   // 42: google.protobuf.Empty
-	(*any.Any)(nil),                       // 43: google.protobuf.Any
+	(*FakeMessageSet)(nil),                // 17: pb2.FakeMessageSet
+	(*FakeMessageSetExtension)(nil),       // 18: pb2.FakeMessageSetExtension
+	(*KnownTypes)(nil),                    // 19: pb2.KnownTypes
+	(*Nests_OptGroup)(nil),                // 20: pb2.Nests.OptGroup
+	(*Nests_RptGroup)(nil),                // 21: pb2.Nests.RptGroup
+	(*Nests_OptGroup_OptNestedGroup)(nil), // 22: pb2.Nests.OptGroup.OptNestedGroup
+	nil,                                   // 23: pb2.Maps.Int32ToStrEntry
+	nil,                                   // 24: pb2.Maps.Sfixed64ToBoolEntry
+	nil,                                   // 25: pb2.Maps.BoolToUint32Entry
+	nil,                                   // 26: pb2.Maps.Uint64ToEnumEntry
+	nil,                                   // 27: pb2.Maps.StrToNestedEntry
+	nil,                                   // 28: pb2.Maps.StrToOneofsEntry
+	nil,                                   // 29: pb2.IndirectRequired.StrToNestedEntry
+	(*wrappers.BoolValue)(nil),            // 30: google.protobuf.BoolValue
+	(*wrappers.Int32Value)(nil),           // 31: google.protobuf.Int32Value
+	(*wrappers.Int64Value)(nil),           // 32: google.protobuf.Int64Value
+	(*wrappers.UInt32Value)(nil),          // 33: google.protobuf.UInt32Value
+	(*wrappers.UInt64Value)(nil),          // 34: google.protobuf.UInt64Value
+	(*wrappers.FloatValue)(nil),           // 35: google.protobuf.FloatValue
+	(*wrappers.DoubleValue)(nil),          // 36: google.protobuf.DoubleValue
+	(*wrappers.StringValue)(nil),          // 37: google.protobuf.StringValue
+	(*wrappers.BytesValue)(nil),           // 38: google.protobuf.BytesValue
+	(*duration.Duration)(nil),             // 39: google.protobuf.Duration
+	(*timestamp.Timestamp)(nil),           // 40: google.protobuf.Timestamp
+	(*_struct.Struct)(nil),                // 41: google.protobuf.Struct
+	(*_struct.ListValue)(nil),             // 42: google.protobuf.ListValue
+	(*_struct.Value)(nil),                 // 43: google.protobuf.Value
+	(*empty.Empty)(nil),                   // 44: google.protobuf.Empty
+	(*any.Any)(nil),                       // 45: google.protobuf.Any
 }
 var xxx_Test_protoFile_depIdxs = []int32{
 	13, // pb2.opt_ext_bool:extendee -> pb2.Extensions
@@ -2158,6 +2285,7 @@
 	13, // pb2.rpt_ext_fixed32:extendee -> pb2.Extensions
 	13, // pb2.rpt_ext_enum:extendee -> pb2.Extensions
 	13, // pb2.rpt_ext_nested:extendee -> pb2.Extensions
+	15, // pb2.message_set_extension:extendee -> pb2.MessageSet
 	13, // pb2.ExtensionsContainer.opt_ext_bool:extendee -> pb2.Extensions
 	13, // pb2.ExtensionsContainer.opt_ext_string:extendee -> pb2.Extensions
 	13, // pb2.ExtensionsContainer.opt_ext_enum:extendee -> pb2.Extensions
@@ -2168,45 +2296,46 @@
 	15, // pb2.MessageSetExtension.message_set_extension:extendee -> pb2.MessageSet
 	15, // pb2.MessageSetExtension.not_message_set_extension:extendee -> pb2.MessageSet
 	15, // pb2.MessageSetExtension.ext_nested:extendee -> pb2.MessageSet
+	17, // pb2.FakeMessageSetExtension.message_set_extension:extendee -> pb2.FakeMessageSet
 	0,  // pb2.Enums.opt_enum:type_name -> pb2.Enum
 	0,  // pb2.Enums.rpt_enum:type_name -> pb2.Enum
 	1,  // pb2.Enums.opt_nested_enum:type_name -> pb2.Enums.NestedEnum
 	1,  // pb2.Enums.rpt_nested_enum:type_name -> pb2.Enums.NestedEnum
 	6,  // pb2.Nests.opt_nested:type_name -> pb2.Nested
-	18, // pb2.Nests.optgroup:type_name -> pb2.Nests.OptGroup
+	20, // pb2.Nests.optgroup:type_name -> pb2.Nests.OptGroup
 	6,  // pb2.Nests.rpt_nested:type_name -> pb2.Nested
-	19, // pb2.Nests.rptgroup:type_name -> pb2.Nests.RptGroup
+	21, // pb2.Nests.rptgroup:type_name -> pb2.Nests.RptGroup
 	6,  // pb2.Nested.opt_nested:type_name -> pb2.Nested
 	0,  // pb2.Requireds.req_enum:type_name -> pb2.Enum
 	6,  // pb2.Requireds.req_nested:type_name -> pb2.Nested
 	6,  // pb2.Oneofs.msg:type_name -> pb2.Nested
-	21, // pb2.Maps.int32_to_str:type_name -> pb2.Maps.Int32ToStrEntry
-	22, // pb2.Maps.sfixed64_to_bool:type_name -> pb2.Maps.Sfixed64ToBoolEntry
-	23, // pb2.Maps.bool_to_uint32:type_name -> pb2.Maps.BoolToUint32Entry
-	24, // pb2.Maps.uint64_to_enum:type_name -> pb2.Maps.Uint64ToEnumEntry
-	25, // pb2.Maps.str_to_nested:type_name -> pb2.Maps.StrToNestedEntry
-	26, // pb2.Maps.str_to_oneofs:type_name -> pb2.Maps.StrToOneofsEntry
+	23, // pb2.Maps.int32_to_str:type_name -> pb2.Maps.Int32ToStrEntry
+	24, // pb2.Maps.sfixed64_to_bool:type_name -> pb2.Maps.Sfixed64ToBoolEntry
+	25, // pb2.Maps.bool_to_uint32:type_name -> pb2.Maps.BoolToUint32Entry
+	26, // pb2.Maps.uint64_to_enum:type_name -> pb2.Maps.Uint64ToEnumEntry
+	27, // pb2.Maps.str_to_nested:type_name -> pb2.Maps.StrToNestedEntry
+	28, // pb2.Maps.str_to_oneofs:type_name -> pb2.Maps.StrToOneofsEntry
 	11, // pb2.IndirectRequired.opt_nested:type_name -> pb2.NestedWithRequired
 	11, // pb2.IndirectRequired.rpt_nested:type_name -> pb2.NestedWithRequired
-	27, // pb2.IndirectRequired.str_to_nested:type_name -> pb2.IndirectRequired.StrToNestedEntry
-	28, // pb2.KnownTypes.opt_bool:type_name -> google.protobuf.BoolValue
-	29, // pb2.KnownTypes.opt_int32:type_name -> google.protobuf.Int32Value
-	30, // pb2.KnownTypes.opt_int64:type_name -> google.protobuf.Int64Value
-	31, // pb2.KnownTypes.opt_uint32:type_name -> google.protobuf.UInt32Value
-	32, // pb2.KnownTypes.opt_uint64:type_name -> google.protobuf.UInt64Value
-	33, // pb2.KnownTypes.opt_float:type_name -> google.protobuf.FloatValue
-	34, // pb2.KnownTypes.opt_double:type_name -> google.protobuf.DoubleValue
-	35, // pb2.KnownTypes.opt_string:type_name -> google.protobuf.StringValue
-	36, // pb2.KnownTypes.opt_bytes:type_name -> google.protobuf.BytesValue
-	37, // pb2.KnownTypes.opt_duration:type_name -> google.protobuf.Duration
-	38, // pb2.KnownTypes.opt_timestamp:type_name -> google.protobuf.Timestamp
-	39, // pb2.KnownTypes.opt_struct:type_name -> google.protobuf.Struct
-	40, // pb2.KnownTypes.opt_list:type_name -> google.protobuf.ListValue
-	41, // pb2.KnownTypes.opt_value:type_name -> google.protobuf.Value
-	42, // pb2.KnownTypes.opt_empty:type_name -> google.protobuf.Empty
-	43, // pb2.KnownTypes.opt_any:type_name -> google.protobuf.Any
+	29, // pb2.IndirectRequired.str_to_nested:type_name -> pb2.IndirectRequired.StrToNestedEntry
+	30, // pb2.KnownTypes.opt_bool:type_name -> google.protobuf.BoolValue
+	31, // pb2.KnownTypes.opt_int32:type_name -> google.protobuf.Int32Value
+	32, // pb2.KnownTypes.opt_int64:type_name -> google.protobuf.Int64Value
+	33, // pb2.KnownTypes.opt_uint32:type_name -> google.protobuf.UInt32Value
+	34, // pb2.KnownTypes.opt_uint64:type_name -> google.protobuf.UInt64Value
+	35, // pb2.KnownTypes.opt_float:type_name -> google.protobuf.FloatValue
+	36, // pb2.KnownTypes.opt_double:type_name -> google.protobuf.DoubleValue
+	37, // pb2.KnownTypes.opt_string:type_name -> google.protobuf.StringValue
+	38, // pb2.KnownTypes.opt_bytes:type_name -> google.protobuf.BytesValue
+	39, // pb2.KnownTypes.opt_duration:type_name -> google.protobuf.Duration
+	40, // pb2.KnownTypes.opt_timestamp:type_name -> google.protobuf.Timestamp
+	41, // pb2.KnownTypes.opt_struct:type_name -> google.protobuf.Struct
+	42, // pb2.KnownTypes.opt_list:type_name -> google.protobuf.ListValue
+	43, // pb2.KnownTypes.opt_value:type_name -> google.protobuf.Value
+	44, // pb2.KnownTypes.opt_empty:type_name -> google.protobuf.Empty
+	45, // pb2.KnownTypes.opt_any:type_name -> google.protobuf.Any
 	6,  // pb2.Nests.OptGroup.opt_nested:type_name -> pb2.Nested
-	20, // pb2.Nests.OptGroup.optnestedgroup:type_name -> pb2.Nests.OptGroup.OptNestedGroup
+	22, // pb2.Nests.OptGroup.optnestedgroup:type_name -> pb2.Nests.OptGroup.OptNestedGroup
 	0,  // pb2.Nests.OptGroup.OptNestedGroup.opt_enum:type_name -> pb2.Enum
 	0,  // pb2.Maps.Uint64ToEnumEntry.value:type_name -> pb2.Enum
 	6,  // pb2.Maps.StrToNestedEntry.value:type_name -> pb2.Nested
@@ -2216,6 +2345,7 @@
 	6,  // pb2.opt_ext_nested:type_name -> pb2.Nested
 	0,  // pb2.rpt_ext_enum:type_name -> pb2.Enum
 	6,  // pb2.rpt_ext_nested:type_name -> pb2.Nested
+	18, // pb2.message_set_extension:type_name -> pb2.FakeMessageSetExtension
 	0,  // pb2.ExtensionsContainer.opt_ext_enum:type_name -> pb2.Enum
 	6,  // pb2.ExtensionsContainer.opt_ext_nested:type_name -> pb2.Nested
 	0,  // pb2.ExtensionsContainer.rpt_ext_enum:type_name -> pb2.Enum
@@ -2223,11 +2353,12 @@
 	16, // pb2.MessageSetExtension.message_set_extension:type_name -> pb2.MessageSetExtension
 	16, // pb2.MessageSetExtension.not_message_set_extension:type_name -> pb2.MessageSetExtension
 	6,  // pb2.MessageSetExtension.ext_nested:type_name -> pb2.Nested
+	18, // pb2.FakeMessageSetExtension.message_set_extension:type_name -> pb2.FakeMessageSetExtension
 }
 
 func init() {
-	var messageTypes [26]protoreflect.MessageType
-	var extensionTypes [17]protoreflect.ExtensionType
+	var messageTypes [28]protoreflect.MessageType
+	var extensionTypes [19]protoreflect.ExtensionType
 	Test_protoFile = protoimpl.FileBuilder{
 		RawDescriptor:        fileDescriptor_c8d7acc1bcec9a72,
 		GoTypes:              xxx_Test_protoFile_goTypes,
@@ -2236,7 +2367,7 @@
 		MessageOutputTypes:   messageTypes[:],
 		ExtensionOutputTypes: extensionTypes[:],
 	}.Init()
-	messageGoTypes := xxx_Test_protoFile_goTypes[2:][:26]
+	messageGoTypes := xxx_Test_protoFile_goTypes[2:][:28]
 	for i, mt := range messageTypes[:] {
 		xxx_Test_protoFile_messageTypes[i].GoType = reflect.TypeOf(messageGoTypes[i])
 		xxx_Test_protoFile_messageTypes[i].PBType = mt
@@ -2248,16 +2379,18 @@
 	E_RptExtFixed32.Type = extensionTypes[4]
 	E_RptExtEnum.Type = extensionTypes[5]
 	E_RptExtNested.Type = extensionTypes[6]
-	E_ExtensionsContainer_OptExtBool.Type = extensionTypes[7]
-	E_ExtensionsContainer_OptExtString.Type = extensionTypes[8]
-	E_ExtensionsContainer_OptExtEnum.Type = extensionTypes[9]
-	E_ExtensionsContainer_OptExtNested.Type = extensionTypes[10]
-	E_ExtensionsContainer_RptExtString.Type = extensionTypes[11]
-	E_ExtensionsContainer_RptExtEnum.Type = extensionTypes[12]
-	E_ExtensionsContainer_RptExtNested.Type = extensionTypes[13]
-	E_MessageSetExtension_MessageSetExtension.Type = extensionTypes[14]
-	E_MessageSetExtension_NotMessageSetExtension.Type = extensionTypes[15]
-	E_MessageSetExtension_ExtNested.Type = extensionTypes[16]
+	E_MessageSetExtension.Type = extensionTypes[7]
+	E_ExtensionsContainer_OptExtBool.Type = extensionTypes[8]
+	E_ExtensionsContainer_OptExtString.Type = extensionTypes[9]
+	E_ExtensionsContainer_OptExtEnum.Type = extensionTypes[10]
+	E_ExtensionsContainer_OptExtNested.Type = extensionTypes[11]
+	E_ExtensionsContainer_RptExtString.Type = extensionTypes[12]
+	E_ExtensionsContainer_RptExtEnum.Type = extensionTypes[13]
+	E_ExtensionsContainer_RptExtNested.Type = extensionTypes[14]
+	E_MessageSetExtension_MessageSetExtension.Type = extensionTypes[15]
+	E_MessageSetExtension_NotMessageSetExtension.Type = extensionTypes[16]
+	E_MessageSetExtension_ExtNested.Type = extensionTypes[17]
+	E_FakeMessageSetExtension_MessageSetExtension.Type = extensionTypes[18]
 	xxx_Test_protoFile_goTypes = nil
 	xxx_Test_protoFile_depIdxs = nil
 }
diff --git a/encoding/textpb/testprotos/pb2/test.proto b/encoding/textpb/testprotos/pb2/test.proto
index 861dd24..b242750 100644
--- a/encoding/textpb/testprotos/pb2/test.proto
+++ b/encoding/textpb/testprotos/pb2/test.proto
@@ -200,6 +200,22 @@
   }
 }
 
+message FakeMessageSet {
+  extensions 4 to max;
+}
+
+message FakeMessageSetExtension {
+  optional string opt_string = 1;
+
+  extend FakeMessageSet {
+    optional FakeMessageSetExtension message_set_extension = 10;
+  }
+}
+
+extend MessageSet {
+  optional FakeMessageSetExtension message_set_extension = 50;
+}
+
 // Message contains well-known type fields.
 message KnownTypes {
   optional google.protobuf.BoolValue opt_bool = 1;