...

Source file src/google.golang.org/protobuf/internal/impl/message_reflect_test.go

Documentation: google.golang.org/protobuf/internal/impl

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package impl_test
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  	"reflect"
    11  	"runtime"
    12  	"strings"
    13  	"sync"
    14  	"testing"
    15  
    16  	"github.com/google/go-cmp/cmp"
    17  	"github.com/google/go-cmp/cmp/cmpopts"
    18  
    19  	"google.golang.org/protobuf/encoding/prototext"
    20  	pimpl "google.golang.org/protobuf/internal/impl"
    21  	"google.golang.org/protobuf/proto"
    22  	"google.golang.org/protobuf/reflect/protodesc"
    23  	"google.golang.org/protobuf/reflect/protoreflect"
    24  	"google.golang.org/protobuf/reflect/protoregistry"
    25  	"google.golang.org/protobuf/testing/protopack"
    26  
    27  	proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2_20180125_92554152"
    28  	testpb "google.golang.org/protobuf/internal/testprotos/test"
    29  	"google.golang.org/protobuf/types/descriptorpb"
    30  )
    31  
    32  // List of test operations to perform on messages, lists, or maps.
    33  type (
    34  	messageOp  interface{ isMessageOp() }
    35  	messageOps []messageOp
    36  
    37  	listOp  interface{ isListOp() }
    38  	listOps []listOp
    39  
    40  	mapOp  interface{ isMapOp() }
    41  	mapOps []mapOp
    42  )
    43  
    44  // Test operations performed on a message.
    45  type (
    46  	// check that the message contents match
    47  	equalMessage struct{ protoreflect.Message }
    48  	// check presence for specific fields in the message
    49  	hasFields map[protoreflect.FieldNumber]bool
    50  	// check that specific message fields match
    51  	getFields map[protoreflect.FieldNumber]protoreflect.Value
    52  	// set specific message fields
    53  	setFields map[protoreflect.FieldNumber]protoreflect.Value
    54  	// clear specific fields in the message
    55  	clearFields []protoreflect.FieldNumber
    56  	// check for the presence of specific oneof member fields.
    57  	whichOneofs map[protoreflect.Name]protoreflect.FieldNumber
    58  	// apply messageOps on each specified message field
    59  	messageFields        map[protoreflect.FieldNumber]messageOps
    60  	messageFieldsMutable map[protoreflect.FieldNumber]messageOps
    61  	// apply listOps on each specified list field
    62  	listFields        map[protoreflect.FieldNumber]listOps
    63  	listFieldsMutable map[protoreflect.FieldNumber]listOps
    64  	// apply mapOps on each specified map fields
    65  	mapFields        map[protoreflect.FieldNumber]mapOps
    66  	mapFieldsMutable map[protoreflect.FieldNumber]mapOps
    67  	// range through all fields and check that they match
    68  	rangeFields map[protoreflect.FieldNumber]protoreflect.Value
    69  )
    70  
    71  func (equalMessage) isMessageOp()         {}
    72  func (hasFields) isMessageOp()            {}
    73  func (getFields) isMessageOp()            {}
    74  func (setFields) isMessageOp()            {}
    75  func (clearFields) isMessageOp()          {}
    76  func (whichOneofs) isMessageOp()          {}
    77  func (messageFields) isMessageOp()        {}
    78  func (messageFieldsMutable) isMessageOp() {}
    79  func (listFields) isMessageOp()           {}
    80  func (listFieldsMutable) isMessageOp()    {}
    81  func (mapFields) isMessageOp()            {}
    82  func (mapFieldsMutable) isMessageOp()     {}
    83  func (rangeFields) isMessageOp()          {}
    84  
    85  // Test operations performed on a list.
    86  type (
    87  	// check that the list contents match
    88  	equalList struct{ protoreflect.List }
    89  	// check that list length matches
    90  	lenList int
    91  	// check that specific list entries match
    92  	getList map[int]protoreflect.Value
    93  	// set specific list entries
    94  	setList map[int]protoreflect.Value
    95  	// append entries to the list
    96  	appendList []protoreflect.Value
    97  	// apply messageOps on a newly appended message
    98  	appendMessageList messageOps
    99  	// truncate the list to the specified length
   100  	truncList int
   101  )
   102  
   103  func (equalList) isListOp()         {}
   104  func (lenList) isListOp()           {}
   105  func (getList) isListOp()           {}
   106  func (setList) isListOp()           {}
   107  func (appendList) isListOp()        {}
   108  func (appendMessageList) isListOp() {}
   109  func (truncList) isListOp()         {}
   110  
   111  // Test operations performed on a map.
   112  type (
   113  	// check that the map contents match
   114  	equalMap struct{ protoreflect.Map }
   115  	// check that map length matches
   116  	lenMap int
   117  	// check presence for specific entries in the map
   118  	hasMap map[interface{}]bool
   119  	// check that specific map entries match
   120  	getMap map[interface{}]protoreflect.Value
   121  	// set specific map entries
   122  	setMap map[interface{}]protoreflect.Value
   123  	// clear specific entries in the map
   124  	clearMap []interface{}
   125  	// apply messageOps on each specified message entry
   126  	messageMap map[interface{}]messageOps
   127  	// range through all entries and check that they match
   128  	rangeMap map[interface{}]protoreflect.Value
   129  )
   130  
   131  func (equalMap) isMapOp()   {}
   132  func (lenMap) isMapOp()     {}
   133  func (hasMap) isMapOp()     {}
   134  func (getMap) isMapOp()     {}
   135  func (setMap) isMapOp()     {}
   136  func (clearMap) isMapOp()   {}
   137  func (messageMap) isMapOp() {}
   138  func (rangeMap) isMapOp()   {}
   139  
   140  type ScalarProto2 struct {
   141  	Bool    *bool    `protobuf:"1"`
   142  	Int32   *int32   `protobuf:"2"`
   143  	Int64   *int64   `protobuf:"3"`
   144  	Uint32  *uint32  `protobuf:"4"`
   145  	Uint64  *uint64  `protobuf:"5"`
   146  	Float32 *float32 `protobuf:"6"`
   147  	Float64 *float64 `protobuf:"7"`
   148  	String  *string  `protobuf:"8"`
   149  	StringA []byte   `protobuf:"9"`
   150  	Bytes   []byte   `protobuf:"10"`
   151  	BytesA  *string  `protobuf:"11"`
   152  
   153  	MyBool    *MyBool    `protobuf:"12"`
   154  	MyInt32   *MyInt32   `protobuf:"13"`
   155  	MyInt64   *MyInt64   `protobuf:"14"`
   156  	MyUint32  *MyUint32  `protobuf:"15"`
   157  	MyUint64  *MyUint64  `protobuf:"16"`
   158  	MyFloat32 *MyFloat32 `protobuf:"17"`
   159  	MyFloat64 *MyFloat64 `protobuf:"18"`
   160  	MyString  *MyString  `protobuf:"19"`
   161  	MyStringA MyBytes    `protobuf:"20"`
   162  	MyBytes   MyBytes    `protobuf:"21"`
   163  	MyBytesA  *MyString  `protobuf:"22"`
   164  }
   165  
   166  func mustMakeEnumDesc(path string, syntax protoreflect.Syntax, enumDesc string) protoreflect.EnumDescriptor {
   167  	s := fmt.Sprintf(`name:%q syntax:%q enum_type:[{%s}]`, path, syntax, enumDesc)
   168  	pb := new(descriptorpb.FileDescriptorProto)
   169  	if err := prototext.Unmarshal([]byte(s), pb); err != nil {
   170  		panic(err)
   171  	}
   172  	fd, err := protodesc.NewFile(pb, nil)
   173  	if err != nil {
   174  		panic(err)
   175  	}
   176  	return fd.Enums().Get(0)
   177  }
   178  
   179  func mustMakeMessageDesc(path string, syntax protoreflect.Syntax, fileDesc, msgDesc string, r protodesc.Resolver) protoreflect.MessageDescriptor {
   180  	s := fmt.Sprintf(`name:%q syntax:%q %s message_type:[{%s}]`, path, syntax, fileDesc, msgDesc)
   181  	pb := new(descriptorpb.FileDescriptorProto)
   182  	if err := prototext.Unmarshal([]byte(s), pb); err != nil {
   183  		panic(err)
   184  	}
   185  	fd, err := protodesc.NewFile(pb, r)
   186  	if err != nil {
   187  		panic(err)
   188  	}
   189  	return fd.Messages().Get(0)
   190  }
   191  
   192  var V = protoreflect.ValueOf
   193  var VE = func(n protoreflect.EnumNumber) protoreflect.Value { return V(n) }
   194  
   195  type (
   196  	MyBool    bool
   197  	MyInt32   int32
   198  	MyInt64   int64
   199  	MyUint32  uint32
   200  	MyUint64  uint64
   201  	MyFloat32 float32
   202  	MyFloat64 float64
   203  	MyString  string
   204  	MyBytes   []byte
   205  
   206  	ListStrings []MyString
   207  	ListBytes   []MyBytes
   208  
   209  	MapStrings map[MyString]MyString
   210  	MapBytes   map[MyString]MyBytes
   211  )
   212  
   213  var scalarProto2Type = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ScalarProto2)), Desc: mustMakeMessageDesc("scalar2.proto", protoreflect.Proto2, "", `
   214  		name: "ScalarProto2"
   215  		field: [
   216  			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_BOOL   default_value:"true"},
   217  			{name:"f2"  number:2  label:LABEL_OPTIONAL type:TYPE_INT32  default_value:"2"},
   218  			{name:"f3"  number:3  label:LABEL_OPTIONAL type:TYPE_INT64  default_value:"3"},
   219  			{name:"f4"  number:4  label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"4"},
   220  			{name:"f5"  number:5  label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"5"},
   221  			{name:"f6"  number:6  label:LABEL_OPTIONAL type:TYPE_FLOAT  default_value:"6"},
   222  			{name:"f7"  number:7  label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"7"},
   223  			{name:"f8"  number:8  label:LABEL_OPTIONAL type:TYPE_STRING default_value:"8"},
   224  			{name:"f9"  number:9  label:LABEL_OPTIONAL type:TYPE_STRING default_value:"9"},
   225  			{name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"10"},
   226  			{name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"11"},
   227  
   228  			{name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BOOL   default_value:"true"},
   229  			{name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_INT32  default_value:"13"},
   230  			{name:"f14" number:14 label:LABEL_OPTIONAL type:TYPE_INT64  default_value:"14"},
   231  			{name:"f15" number:15 label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"15"},
   232  			{name:"f16" number:16 label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"16"},
   233  			{name:"f17" number:17 label:LABEL_OPTIONAL type:TYPE_FLOAT  default_value:"17"},
   234  			{name:"f18" number:18 label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"18"},
   235  			{name:"f19" number:19 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"19"},
   236  			{name:"f20" number:20 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"20"},
   237  			{name:"f21" number:21 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"21"},
   238  			{name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"22"}
   239  		]
   240  	`, nil),
   241  }
   242  
   243  func (m *ScalarProto2) ProtoReflect() protoreflect.Message { return scalarProto2Type.MessageOf(m) }
   244  
   245  func TestScalarProto2(t *testing.T) {
   246  	testMessage(t, nil, new(ScalarProto2).ProtoReflect(), messageOps{
   247  		hasFields{
   248  			1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
   249  			12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
   250  		},
   251  		getFields{
   252  			1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
   253  			12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
   254  		},
   255  		setFields{
   256  			1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
   257  			12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
   258  		},
   259  		hasFields{
   260  			1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
   261  			12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
   262  		},
   263  		equalMessage{(&ScalarProto2{
   264  			new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
   265  			new(MyBool), new(MyInt32), new(MyInt64), new(MyUint32), new(MyUint64), new(MyFloat32), new(MyFloat64), new(MyString), MyBytes{}, MyBytes{}, new(MyString),
   266  		}).ProtoReflect()},
   267  		clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
   268  		equalMessage{new(ScalarProto2).ProtoReflect()},
   269  
   270  		// Setting a bytes field nil empty bytes should preserve presence.
   271  		setFields{10: V([]byte(nil)), 11: V([]byte(nil)), 21: V([]byte(nil)), 22: V([]byte(nil))},
   272  		getFields{10: V([]byte{}), 11: V([]byte(nil)), 21: V([]byte{}), 22: V([]byte(nil))},
   273  		hasFields{10: true, 11: true, 21: true, 22: true},
   274  	})
   275  
   276  	// Test read-only operations on nil message.
   277  	testMessage(t, nil, (*ScalarProto2)(nil).ProtoReflect(), messageOps{
   278  		hasFields{
   279  			1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
   280  			12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
   281  		},
   282  		getFields{
   283  			1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
   284  			12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
   285  		},
   286  	})
   287  }
   288  
   289  type ScalarProto3 struct {
   290  	Bool    bool    `protobuf:"1"`
   291  	Int32   int32   `protobuf:"2"`
   292  	Int64   int64   `protobuf:"3"`
   293  	Uint32  uint32  `protobuf:"4"`
   294  	Uint64  uint64  `protobuf:"5"`
   295  	Float32 float32 `protobuf:"6"`
   296  	Float64 float64 `protobuf:"7"`
   297  	String  string  `protobuf:"8"`
   298  	StringA []byte  `protobuf:"9"`
   299  	Bytes   []byte  `protobuf:"10"`
   300  	BytesA  string  `protobuf:"11"`
   301  
   302  	MyBool    MyBool    `protobuf:"12"`
   303  	MyInt32   MyInt32   `protobuf:"13"`
   304  	MyInt64   MyInt64   `protobuf:"14"`
   305  	MyUint32  MyUint32  `protobuf:"15"`
   306  	MyUint64  MyUint64  `protobuf:"16"`
   307  	MyFloat32 MyFloat32 `protobuf:"17"`
   308  	MyFloat64 MyFloat64 `protobuf:"18"`
   309  	MyString  MyString  `protobuf:"19"`
   310  	MyStringA MyBytes   `protobuf:"20"`
   311  	MyBytes   MyBytes   `protobuf:"21"`
   312  	MyBytesA  MyString  `protobuf:"22"`
   313  }
   314  
   315  var scalarProto3Type = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ScalarProto3)), Desc: mustMakeMessageDesc("scalar3.proto", protoreflect.Proto3, "", `
   316  		name: "ScalarProto3"
   317  		field: [
   318  			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_BOOL},
   319  			{name:"f2"  number:2  label:LABEL_OPTIONAL type:TYPE_INT32},
   320  			{name:"f3"  number:3  label:LABEL_OPTIONAL type:TYPE_INT64},
   321  			{name:"f4"  number:4  label:LABEL_OPTIONAL type:TYPE_UINT32},
   322  			{name:"f5"  number:5  label:LABEL_OPTIONAL type:TYPE_UINT64},
   323  			{name:"f6"  number:6  label:LABEL_OPTIONAL type:TYPE_FLOAT},
   324  			{name:"f7"  number:7  label:LABEL_OPTIONAL type:TYPE_DOUBLE},
   325  			{name:"f8"  number:8  label:LABEL_OPTIONAL type:TYPE_STRING},
   326  			{name:"f9"  number:9  label:LABEL_OPTIONAL type:TYPE_STRING},
   327  			{name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_BYTES},
   328  			{name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES},
   329  
   330  			{name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BOOL},
   331  			{name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_INT32},
   332  			{name:"f14" number:14 label:LABEL_OPTIONAL type:TYPE_INT64},
   333  			{name:"f15" number:15 label:LABEL_OPTIONAL type:TYPE_UINT32},
   334  			{name:"f16" number:16 label:LABEL_OPTIONAL type:TYPE_UINT64},
   335  			{name:"f17" number:17 label:LABEL_OPTIONAL type:TYPE_FLOAT},
   336  			{name:"f18" number:18 label:LABEL_OPTIONAL type:TYPE_DOUBLE},
   337  			{name:"f19" number:19 label:LABEL_OPTIONAL type:TYPE_STRING},
   338  			{name:"f20" number:20 label:LABEL_OPTIONAL type:TYPE_STRING},
   339  			{name:"f21" number:21 label:LABEL_OPTIONAL type:TYPE_BYTES},
   340  			{name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES}
   341  		]
   342  	`, nil),
   343  }
   344  
   345  func (m *ScalarProto3) ProtoReflect() protoreflect.Message { return scalarProto3Type.MessageOf(m) }
   346  
   347  func TestScalarProto3(t *testing.T) {
   348  	testMessage(t, nil, new(ScalarProto3).ProtoReflect(), messageOps{
   349  		hasFields{
   350  			1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
   351  			12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
   352  		},
   353  		getFields{
   354  			1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
   355  			12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
   356  		},
   357  		setFields{
   358  			1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
   359  			12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
   360  		},
   361  		hasFields{
   362  			1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
   363  			12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
   364  		},
   365  		equalMessage{new(ScalarProto3).ProtoReflect()},
   366  		setFields{
   367  			1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
   368  			12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
   369  		},
   370  		hasFields{
   371  			1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
   372  			12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
   373  		},
   374  		equalMessage{(&ScalarProto3{
   375  			true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
   376  			true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
   377  		}).ProtoReflect()},
   378  		setFields{
   379  			2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
   380  		},
   381  		hasFields{
   382  			2: true, 3: true, 6: true, 7: true,
   383  		},
   384  		clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
   385  		equalMessage{new(ScalarProto3).ProtoReflect()},
   386  
   387  		// Verify that -0 triggers proper Has behavior.
   388  		hasFields{6: false, 7: false},
   389  		setFields{6: V(float32(math.Copysign(0, -1))), 7: V(float64(math.Copysign(0, -1)))},
   390  		hasFields{6: true, 7: true},
   391  
   392  		// Setting a bytes field to non-nil empty bytes should not preserve presence.
   393  		setFields{10: V([]byte{}), 11: V([]byte{}), 21: V([]byte{}), 22: V([]byte{})},
   394  		getFields{10: V([]byte(nil)), 11: V([]byte(nil)), 21: V([]byte(nil)), 22: V([]byte(nil))},
   395  		hasFields{10: false, 11: false, 21: false, 22: false},
   396  	})
   397  
   398  	// Test read-only operations on nil message.
   399  	testMessage(t, nil, (*ScalarProto3)(nil).ProtoReflect(), messageOps{
   400  		hasFields{
   401  			1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
   402  			12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
   403  		},
   404  		getFields{
   405  			1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
   406  			12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
   407  		},
   408  	})
   409  }
   410  
   411  type ListScalars struct {
   412  	Bools    []bool    `protobuf:"1"`
   413  	Int32s   []int32   `protobuf:"2"`
   414  	Int64s   []int64   `protobuf:"3"`
   415  	Uint32s  []uint32  `protobuf:"4"`
   416  	Uint64s  []uint64  `protobuf:"5"`
   417  	Float32s []float32 `protobuf:"6"`
   418  	Float64s []float64 `protobuf:"7"`
   419  	Strings  []string  `protobuf:"8"`
   420  	StringsA [][]byte  `protobuf:"9"`
   421  	Bytes    [][]byte  `protobuf:"10"`
   422  	BytesA   []string  `protobuf:"11"`
   423  
   424  	MyStrings1 []MyString `protobuf:"12"`
   425  	MyStrings2 []MyBytes  `protobuf:"13"`
   426  	MyBytes1   []MyBytes  `protobuf:"14"`
   427  	MyBytes2   []MyString `protobuf:"15"`
   428  
   429  	MyStrings3 ListStrings `protobuf:"16"`
   430  	MyStrings4 ListBytes   `protobuf:"17"`
   431  	MyBytes3   ListBytes   `protobuf:"18"`
   432  	MyBytes4   ListStrings `protobuf:"19"`
   433  }
   434  
   435  var listScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ListScalars)), Desc: mustMakeMessageDesc("list-scalars.proto", protoreflect.Proto2, "", `
   436  		name: "ListScalars"
   437  		field: [
   438  			{name:"f1"  number:1  label:LABEL_REPEATED type:TYPE_BOOL},
   439  			{name:"f2"  number:2  label:LABEL_REPEATED type:TYPE_INT32},
   440  			{name:"f3"  number:3  label:LABEL_REPEATED type:TYPE_INT64},
   441  			{name:"f4"  number:4  label:LABEL_REPEATED type:TYPE_UINT32},
   442  			{name:"f5"  number:5  label:LABEL_REPEATED type:TYPE_UINT64},
   443  			{name:"f6"  number:6  label:LABEL_REPEATED type:TYPE_FLOAT},
   444  			{name:"f7"  number:7  label:LABEL_REPEATED type:TYPE_DOUBLE},
   445  			{name:"f8"  number:8  label:LABEL_REPEATED type:TYPE_STRING},
   446  			{name:"f9"  number:9  label:LABEL_REPEATED type:TYPE_STRING},
   447  			{name:"f10" number:10 label:LABEL_REPEATED type:TYPE_BYTES},
   448  			{name:"f11" number:11 label:LABEL_REPEATED type:TYPE_BYTES},
   449  
   450  			{name:"f12" number:12 label:LABEL_REPEATED type:TYPE_STRING},
   451  			{name:"f13" number:13 label:LABEL_REPEATED type:TYPE_STRING},
   452  			{name:"f14" number:14 label:LABEL_REPEATED type:TYPE_BYTES},
   453  			{name:"f15" number:15 label:LABEL_REPEATED type:TYPE_BYTES},
   454  
   455  			{name:"f16" number:16 label:LABEL_REPEATED type:TYPE_STRING},
   456  			{name:"f17" number:17 label:LABEL_REPEATED type:TYPE_STRING},
   457  			{name:"f18" number:18 label:LABEL_REPEATED type:TYPE_BYTES},
   458  			{name:"f19" number:19 label:LABEL_REPEATED type:TYPE_BYTES}
   459  		]
   460  	`, nil),
   461  }
   462  
   463  func (m *ListScalars) ProtoReflect() protoreflect.Message { return listScalarsType.MessageOf(m) }
   464  
   465  func TestListScalars(t *testing.T) {
   466  	empty := new(ListScalars).ProtoReflect()
   467  	want := (&ListScalars{
   468  		Bools:    []bool{true, false, true},
   469  		Int32s:   []int32{2, math.MinInt32, math.MaxInt32},
   470  		Int64s:   []int64{3, math.MinInt64, math.MaxInt64},
   471  		Uint32s:  []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
   472  		Uint64s:  []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
   473  		Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
   474  		Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
   475  		Strings:  []string{"8", "", "eight"},
   476  		StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
   477  		Bytes:    [][]byte{[]byte("10"), nil, []byte("ten")},
   478  		BytesA:   []string{"11", "", "eleven"},
   479  
   480  		MyStrings1: []MyString{"12", "", "twelve"},
   481  		MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
   482  		MyBytes1:   []MyBytes{[]byte("14"), nil, []byte("fourteen")},
   483  		MyBytes2:   []MyString{"15", "", "fifteen"},
   484  
   485  		MyStrings3: ListStrings{"16", "", "sixteen"},
   486  		MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
   487  		MyBytes3:   ListBytes{[]byte("18"), nil, []byte("eighteen")},
   488  		MyBytes4:   ListStrings{"19", "", "nineteen"},
   489  	}).ProtoReflect()
   490  
   491  	testMessage(t, nil, new(ListScalars).ProtoReflect(), messageOps{
   492  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false},
   493  		getFields{1: getField(empty, 1), 3: getField(empty, 3), 5: getField(empty, 5), 7: getField(empty, 7), 9: getField(empty, 9), 11: getField(empty, 11), 13: getField(empty, 13), 15: getField(empty, 15), 17: getField(empty, 17), 19: getField(empty, 19)},
   494  		setFields{1: getField(want, 1), 3: getField(want, 3), 5: getField(want, 5), 7: getField(want, 7), 9: getField(want, 9), 11: getField(want, 11), 13: getField(want, 13), 15: getField(want, 15), 17: getField(want, 17), 19: getField(want, 19)},
   495  		listFieldsMutable{
   496  			2: {
   497  				lenList(0),
   498  				appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
   499  				getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
   500  				equalList{getField(want, 2).List()},
   501  			},
   502  			4: {
   503  				appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
   504  				setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
   505  				lenList(3),
   506  			},
   507  			6: {
   508  				appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
   509  				equalList{getField(want, 6).List()},
   510  			},
   511  			8: {
   512  				appendList{V(""), V(""), V(""), V(""), V(""), V("")},
   513  				lenList(6),
   514  				setList{0: V("8"), 2: V("eight")},
   515  				truncList(3),
   516  				equalList{getField(want, 8).List()},
   517  			},
   518  			10: {
   519  				appendList{V([]byte(nil)), V([]byte(nil))},
   520  				setList{0: V([]byte("10"))},
   521  				appendList{V([]byte("wrong"))},
   522  				setList{2: V([]byte("ten"))},
   523  				equalList{getField(want, 10).List()},
   524  			},
   525  			12: {
   526  				appendList{V("12"), V("wrong"), V("twelve")},
   527  				setList{1: V("")},
   528  				equalList{getField(want, 12).List()},
   529  			},
   530  			14: {
   531  				appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
   532  				equalList{getField(want, 14).List()},
   533  			},
   534  			16: {
   535  				appendList{V("16"), V(""), V("sixteen"), V("extra")},
   536  				truncList(3),
   537  				equalList{getField(want, 16).List()},
   538  			},
   539  			18: {
   540  				appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
   541  				equalList{getField(want, 18).List()},
   542  			},
   543  		},
   544  		hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true},
   545  		equalMessage{want},
   546  		clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
   547  		equalMessage{empty},
   548  	})
   549  
   550  	// Test read-only operations on nil message.
   551  	testMessage(t, nil, (*ListScalars)(nil).ProtoReflect(), messageOps{
   552  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false},
   553  		listFields{2: {lenList(0)}, 4: {lenList(0)}, 6: {lenList(0)}, 8: {lenList(0)}, 10: {lenList(0)}, 12: {lenList(0)}, 14: {lenList(0)}, 16: {lenList(0)}, 18: {lenList(0)}},
   554  	})
   555  }
   556  
   557  type MapScalars struct {
   558  	KeyBools   map[bool]string   `protobuf:"1"`
   559  	KeyInt32s  map[int32]string  `protobuf:"2"`
   560  	KeyInt64s  map[int64]string  `protobuf:"3"`
   561  	KeyUint32s map[uint32]string `protobuf:"4"`
   562  	KeyUint64s map[uint64]string `protobuf:"5"`
   563  	KeyStrings map[string]string `protobuf:"6"`
   564  
   565  	ValBools    map[string]bool    `protobuf:"7"`
   566  	ValInt32s   map[string]int32   `protobuf:"8"`
   567  	ValInt64s   map[string]int64   `protobuf:"9"`
   568  	ValUint32s  map[string]uint32  `protobuf:"10"`
   569  	ValUint64s  map[string]uint64  `protobuf:"11"`
   570  	ValFloat32s map[string]float32 `protobuf:"12"`
   571  	ValFloat64s map[string]float64 `protobuf:"13"`
   572  	ValStrings  map[string]string  `protobuf:"14"`
   573  	ValStringsA map[string][]byte  `protobuf:"15"`
   574  	ValBytes    map[string][]byte  `protobuf:"16"`
   575  	ValBytesA   map[string]string  `protobuf:"17"`
   576  
   577  	MyStrings1 map[MyString]MyString `protobuf:"18"`
   578  	MyStrings2 map[MyString]MyBytes  `protobuf:"19"`
   579  	MyBytes1   map[MyString]MyBytes  `protobuf:"20"`
   580  	MyBytes2   map[MyString]MyString `protobuf:"21"`
   581  
   582  	MyStrings3 MapStrings `protobuf:"22"`
   583  	MyStrings4 MapBytes   `protobuf:"23"`
   584  	MyBytes3   MapBytes   `protobuf:"24"`
   585  	MyBytes4   MapStrings `protobuf:"25"`
   586  }
   587  
   588  var mapScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(MapScalars)), Desc: mustMakeMessageDesc("map-scalars.proto", protoreflect.Proto2, "", `
   589  		name: "MapScalars"
   590  		field: [
   591  			{name:"f1"  number:1  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F1Entry"},
   592  			{name:"f2"  number:2  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F2Entry"},
   593  			{name:"f3"  number:3  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F3Entry"},
   594  			{name:"f4"  number:4  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F4Entry"},
   595  			{name:"f5"  number:5  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F5Entry"},
   596  			{name:"f6"  number:6  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F6Entry"},
   597  
   598  			{name:"f7"  number:7  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F7Entry"},
   599  			{name:"f8"  number:8  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F8Entry"},
   600  			{name:"f9"  number:9  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F9Entry"},
   601  			{name:"f10" number:10 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F10Entry"},
   602  			{name:"f11" number:11 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F11Entry"},
   603  			{name:"f12" number:12 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F12Entry"},
   604  			{name:"f13" number:13 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F13Entry"},
   605  			{name:"f14" number:14 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F14Entry"},
   606  			{name:"f15" number:15 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F15Entry"},
   607  			{name:"f16" number:16 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F16Entry"},
   608  			{name:"f17" number:17 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F17Entry"},
   609  
   610  			{name:"f18" number:18 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F18Entry"},
   611  			{name:"f19" number:19 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F19Entry"},
   612  			{name:"f20" number:20 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F20Entry"},
   613  			{name:"f21" number:21 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F21Entry"},
   614  
   615  			{name:"f22" number:22 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F22Entry"},
   616  			{name:"f23" number:23 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F23Entry"},
   617  			{name:"f24" number:24 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F24Entry"},
   618  			{name:"f25" number:25 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F25Entry"}
   619  		]
   620  		nested_type: [
   621  			{name:"F1Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL},   {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   622  			{name:"F2Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_INT32},  {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   623  			{name:"F3Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_INT64},  {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   624  			{name:"F4Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   625  			{name:"F5Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_UINT64}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   626  			{name:"F6Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   627  
   628  			{name:"F7Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BOOL}]   options:{map_entry:true}},
   629  			{name:"F8Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_INT32}]  options:{map_entry:true}},
   630  			{name:"F9Entry"  field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_INT64}]  options:{map_entry:true}},
   631  			{name:"F10Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_UINT32}] options:{map_entry:true}},
   632  			{name:"F11Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_UINT64}] options:{map_entry:true}},
   633  			{name:"F12Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_FLOAT}]  options:{map_entry:true}},
   634  			{name:"F13Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_DOUBLE}] options:{map_entry:true}},
   635  			{name:"F14Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   636  			{name:"F15Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   637  			{name:"F16Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}]  options:{map_entry:true}},
   638  			{name:"F17Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}]  options:{map_entry:true}},
   639  
   640  			{name:"F18Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   641  			{name:"F19Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   642  			{name:"F20Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}]  options:{map_entry:true}},
   643  			{name:"F21Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}]  options:{map_entry:true}},
   644  
   645  			{name:"F22Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   646  			{name:"F23Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
   647  			{name:"F24Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}]  options:{map_entry:true}},
   648  			{name:"F25Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}]  options:{map_entry:true}}
   649  		]
   650  	`, nil),
   651  }
   652  
   653  func (m *MapScalars) ProtoReflect() protoreflect.Message { return mapScalarsType.MessageOf(m) }
   654  
   655  func TestMapScalars(t *testing.T) {
   656  	empty := new(MapScalars).ProtoReflect()
   657  	want := (&MapScalars{
   658  		KeyBools:   map[bool]string{true: "true", false: "false"},
   659  		KeyInt32s:  map[int32]string{0: "zero", -1: "one", 2: "two"},
   660  		KeyInt64s:  map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
   661  		KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
   662  		KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
   663  		KeyStrings: map[string]string{"": "", "foo": "bar"},
   664  
   665  		ValBools:    map[string]bool{"true": true, "false": false},
   666  		ValInt32s:   map[string]int32{"one": 1, "two": 2, "three": 3},
   667  		ValInt64s:   map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
   668  		ValUint32s:  map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
   669  		ValUint64s:  map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
   670  		ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
   671  		ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
   672  		ValStrings:  map[string]string{"s1": "s1", "s2": "s2"},
   673  		ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
   674  		ValBytes:    map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
   675  		ValBytesA:   map[string]string{"s1": "s1", "s2": "s2"},
   676  
   677  		MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
   678  		MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
   679  		MyBytes1:   map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
   680  		MyBytes2:   map[MyString]MyString{"s1": "s1", "s2": "s2"},
   681  
   682  		MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
   683  		MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
   684  		MyBytes3:   MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
   685  		MyBytes4:   MapStrings{"s1": "s1", "s2": "s2"},
   686  	}).ProtoReflect()
   687  
   688  	testMessage(t, nil, new(MapScalars).ProtoReflect(), messageOps{
   689  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false, 23: false, 24: false, 25: false},
   690  		getFields{1: getField(empty, 1), 3: getField(empty, 3), 5: getField(empty, 5), 7: getField(empty, 7), 9: getField(empty, 9), 11: getField(empty, 11), 13: getField(empty, 13), 15: getField(empty, 15), 17: getField(empty, 17), 19: getField(empty, 19), 21: getField(empty, 21), 23: getField(empty, 23), 25: getField(empty, 25)},
   691  		setFields{1: getField(want, 1), 3: getField(want, 3), 5: getField(want, 5), 7: getField(want, 7), 9: getField(want, 9), 11: getField(want, 11), 13: getField(want, 13), 15: getField(want, 15), 17: getField(want, 17), 19: getField(want, 19), 21: getField(want, 21), 23: getField(want, 23), 25: getField(want, 25)},
   692  		mapFieldsMutable{
   693  			2: {
   694  				lenMap(0),
   695  				hasMap{int32(0): false, int32(-1): false, int32(2): false},
   696  				setMap{int32(0): V("zero")},
   697  				lenMap(1),
   698  				hasMap{int32(0): true, int32(-1): false, int32(2): false},
   699  				setMap{int32(-1): V("one")},
   700  				lenMap(2),
   701  				hasMap{int32(0): true, int32(-1): true, int32(2): false},
   702  				setMap{int32(2): V("two")},
   703  				lenMap(3),
   704  				hasMap{int32(0): true, int32(-1): true, int32(2): true},
   705  			},
   706  			4: {
   707  				setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
   708  				equalMap{getField(want, 4).Map()},
   709  			},
   710  			6: {
   711  				clearMap{"noexist"},
   712  				setMap{"foo": V("bar")},
   713  				setMap{"": V("empty")},
   714  				getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
   715  				setMap{"": V(""), "extra": V("extra")},
   716  				clearMap{"extra", "noexist"},
   717  			},
   718  			8: {
   719  				equalMap{getField(empty, 8).Map()},
   720  				setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
   721  			},
   722  			10: {
   723  				setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
   724  				lenMap(3),
   725  				equalMap{getField(want, 10).Map()},
   726  				getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
   727  			},
   728  			12: {
   729  				setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
   730  				clearMap{"e", "phi"},
   731  				rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
   732  			},
   733  			14: {
   734  				equalMap{getField(empty, 14).Map()},
   735  				setMap{"s1": V("s1"), "s2": V("s2")},
   736  			},
   737  			16: {
   738  				setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
   739  				equalMap{getField(want, 16).Map()},
   740  			},
   741  			18: {
   742  				hasMap{"s1": false, "s2": false, "s3": false},
   743  				setMap{"s1": V("s1"), "s2": V("s2")},
   744  				hasMap{"s1": true, "s2": true, "s3": false},
   745  			},
   746  			20: {
   747  				equalMap{getField(empty, 20).Map()},
   748  				setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
   749  			},
   750  			22: {
   751  				rangeMap{},
   752  				setMap{"s1": V("s1"), "s2": V("s2")},
   753  				rangeMap{"s1": V("s1"), "s2": V("s2")},
   754  				lenMap(2),
   755  			},
   756  			24: {
   757  				setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
   758  				equalMap{getField(want, 24).Map()},
   759  			},
   760  		},
   761  		hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true, 23: true, 24: true, 25: true},
   762  		equalMessage{want},
   763  		clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25},
   764  		equalMessage{empty},
   765  	})
   766  
   767  	// Test read-only operations on nil message.
   768  	testMessage(t, nil, (*MapScalars)(nil).ProtoReflect(), messageOps{
   769  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false, 23: false, 24: false, 25: false},
   770  		mapFields{2: {lenMap(0)}, 4: {lenMap(0)}, 6: {lenMap(0)}, 8: {lenMap(0)}, 10: {lenMap(0)}, 12: {lenMap(0)}, 14: {lenMap(0)}, 16: {lenMap(0)}, 18: {lenMap(0)}, 20: {lenMap(0)}, 22: {lenMap(0)}, 24: {lenMap(0)}},
   771  	})
   772  }
   773  
   774  type OneofScalars struct {
   775  	Union isOneofScalars_Union `protobuf_oneof:"union"`
   776  }
   777  
   778  var oneofScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(OneofScalars)), Desc: mustMakeMessageDesc("oneof-scalars.proto", protoreflect.Proto2, "", `
   779  		name: "OneofScalars"
   780  		field: [
   781  			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_BOOL   default_value:"true" oneof_index:0},
   782  			{name:"f2"  number:2  label:LABEL_OPTIONAL type:TYPE_INT32  default_value:"2"    oneof_index:0},
   783  			{name:"f3"  number:3  label:LABEL_OPTIONAL type:TYPE_INT64  default_value:"3"    oneof_index:0},
   784  			{name:"f4"  number:4  label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"4"    oneof_index:0},
   785  			{name:"f5"  number:5  label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"5"    oneof_index:0},
   786  			{name:"f6"  number:6  label:LABEL_OPTIONAL type:TYPE_FLOAT  default_value:"6"    oneof_index:0},
   787  			{name:"f7"  number:7  label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"7"    oneof_index:0},
   788  			{name:"f8"  number:8  label:LABEL_OPTIONAL type:TYPE_STRING default_value:"8"    oneof_index:0},
   789  			{name:"f9"  number:9  label:LABEL_OPTIONAL type:TYPE_STRING default_value:"9"    oneof_index:0},
   790  			{name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"10"   oneof_index:0},
   791  			{name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"11"   oneof_index:0},
   792  			{name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"12"   oneof_index:0},
   793  			{name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_BYTES  default_value:"13"   oneof_index:0}
   794  		]
   795  		oneof_decl: [{name:"union"}]
   796  	`, nil),
   797  }
   798  
   799  func (m *OneofScalars) ProtoReflect() protoreflect.Message { return oneofScalarsType.MessageOf(m) }
   800  
   801  func (*OneofScalars) XXX_OneofWrappers() []interface{} {
   802  	return []interface{}{
   803  		(*OneofScalars_Bool)(nil),
   804  		(*OneofScalars_Int32)(nil),
   805  		(*OneofScalars_Int64)(nil),
   806  		(*OneofScalars_Uint32)(nil),
   807  		(*OneofScalars_Uint64)(nil),
   808  		(*OneofScalars_Float32)(nil),
   809  		(*OneofScalars_Float64)(nil),
   810  		(*OneofScalars_String)(nil),
   811  		(*OneofScalars_StringA)(nil),
   812  		(*OneofScalars_StringB)(nil),
   813  		(*OneofScalars_Bytes)(nil),
   814  		(*OneofScalars_BytesA)(nil),
   815  		(*OneofScalars_BytesB)(nil),
   816  	}
   817  }
   818  
   819  type (
   820  	isOneofScalars_Union interface {
   821  		isOneofScalars_Union()
   822  	}
   823  	OneofScalars_Bool struct {
   824  		Bool bool `protobuf:"1"`
   825  	}
   826  	OneofScalars_Int32 struct {
   827  		Int32 MyInt32 `protobuf:"2"`
   828  	}
   829  	OneofScalars_Int64 struct {
   830  		Int64 int64 `protobuf:"3"`
   831  	}
   832  	OneofScalars_Uint32 struct {
   833  		Uint32 MyUint32 `protobuf:"4"`
   834  	}
   835  	OneofScalars_Uint64 struct {
   836  		Uint64 uint64 `protobuf:"5"`
   837  	}
   838  	OneofScalars_Float32 struct {
   839  		Float32 MyFloat32 `protobuf:"6"`
   840  	}
   841  	OneofScalars_Float64 struct {
   842  		Float64 float64 `protobuf:"7"`
   843  	}
   844  	OneofScalars_String struct {
   845  		String string `protobuf:"8"`
   846  	}
   847  	OneofScalars_StringA struct {
   848  		StringA []byte `protobuf:"9"`
   849  	}
   850  	OneofScalars_StringB struct {
   851  		StringB MyString `protobuf:"10"`
   852  	}
   853  	OneofScalars_Bytes struct {
   854  		Bytes []byte `protobuf:"11"`
   855  	}
   856  	OneofScalars_BytesA struct {
   857  		BytesA string `protobuf:"12"`
   858  	}
   859  	OneofScalars_BytesB struct {
   860  		BytesB MyBytes `protobuf:"13"`
   861  	}
   862  )
   863  
   864  func (*OneofScalars_Bool) isOneofScalars_Union()    {}
   865  func (*OneofScalars_Int32) isOneofScalars_Union()   {}
   866  func (*OneofScalars_Int64) isOneofScalars_Union()   {}
   867  func (*OneofScalars_Uint32) isOneofScalars_Union()  {}
   868  func (*OneofScalars_Uint64) isOneofScalars_Union()  {}
   869  func (*OneofScalars_Float32) isOneofScalars_Union() {}
   870  func (*OneofScalars_Float64) isOneofScalars_Union() {}
   871  func (*OneofScalars_String) isOneofScalars_Union()  {}
   872  func (*OneofScalars_StringA) isOneofScalars_Union() {}
   873  func (*OneofScalars_StringB) isOneofScalars_Union() {}
   874  func (*OneofScalars_Bytes) isOneofScalars_Union()   {}
   875  func (*OneofScalars_BytesA) isOneofScalars_Union()  {}
   876  func (*OneofScalars_BytesB) isOneofScalars_Union()  {}
   877  
   878  func TestOneofs(t *testing.T) {
   879  	empty := &OneofScalars{}
   880  	want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
   881  	want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
   882  	want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
   883  	want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
   884  	want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
   885  	want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
   886  	want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
   887  	want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
   888  	want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
   889  	want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
   890  	want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
   891  	want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
   892  	want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
   893  
   894  	testMessage(t, nil, new(OneofScalars).ProtoReflect(), messageOps{
   895  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
   896  		getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("13"))},
   897  		whichOneofs{"union": 0},
   898  
   899  		setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1.ProtoReflect()},
   900  		setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2.ProtoReflect()},
   901  		setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3.ProtoReflect()},
   902  		setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4.ProtoReflect()},
   903  		setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5.ProtoReflect()},
   904  		setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6.ProtoReflect()},
   905  		setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7.ProtoReflect()},
   906  
   907  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
   908  		whichOneofs{"union": 7},
   909  
   910  		setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8.ProtoReflect()},
   911  		setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9.ProtoReflect()},
   912  		setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10.ProtoReflect()},
   913  		setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11.ProtoReflect()},
   914  		setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12.ProtoReflect()},
   915  		setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13.ProtoReflect()},
   916  
   917  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: true},
   918  		getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("130"))},
   919  		clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
   920  		whichOneofs{"union": 13},
   921  		equalMessage{want13.ProtoReflect()},
   922  		clearFields{13},
   923  		whichOneofs{"union": 0},
   924  		equalMessage{empty.ProtoReflect()},
   925  	})
   926  
   927  	// Test read-only operations on nil message.
   928  	testMessage(t, nil, (*OneofScalars)(nil).ProtoReflect(), messageOps{
   929  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
   930  		getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("13"))},
   931  	})
   932  }
   933  
   934  type EnumProto2 int32
   935  
   936  var enumProto2Desc = mustMakeEnumDesc("enum2.proto", protoreflect.Proto2, `
   937  	name:  "EnumProto2"
   938  	value: [{name:"DEAD" number:0xdead}, {name:"BEEF" number:0xbeef}]
   939  `)
   940  
   941  func (e EnumProto2) Descriptor() protoreflect.EnumDescriptor         { return enumProto2Desc }
   942  func (e EnumProto2) Type() protoreflect.EnumType                     { return e }
   943  func (e EnumProto2) Enum() *EnumProto2                               { return &e }
   944  func (e EnumProto2) Number() protoreflect.EnumNumber                 { return protoreflect.EnumNumber(e) }
   945  func (t EnumProto2) New(n protoreflect.EnumNumber) protoreflect.Enum { return EnumProto2(n) }
   946  
   947  type EnumProto3 int32
   948  
   949  var enumProto3Desc = mustMakeEnumDesc("enum3.proto", protoreflect.Proto3, `
   950  	name:  "EnumProto3",
   951  	value: [{name:"ALPHA" number:0}, {name:"BRAVO" number:1}]
   952  `)
   953  
   954  func (e EnumProto3) Descriptor() protoreflect.EnumDescriptor         { return enumProto3Desc }
   955  func (e EnumProto3) Type() protoreflect.EnumType                     { return e }
   956  func (e EnumProto3) Enum() *EnumProto3                               { return &e }
   957  func (e EnumProto3) Number() protoreflect.EnumNumber                 { return protoreflect.EnumNumber(e) }
   958  func (t EnumProto3) New(n protoreflect.EnumNumber) protoreflect.Enum { return EnumProto3(n) }
   959  
   960  type EnumMessages struct {
   961  	EnumP2        *EnumProto2              `protobuf:"1"`
   962  	EnumP3        *EnumProto3              `protobuf:"2"`
   963  	MessageLegacy *proto2_20180125.Message `protobuf:"3"`
   964  	MessageCycle  *EnumMessages            `protobuf:"4"`
   965  	EnumList      []EnumProto2             `protobuf:"5"`
   966  	MessageList   []*ScalarProto2          `protobuf:"6"`
   967  	EnumMap       map[string]EnumProto3    `protobuf:"7"`
   968  	MessageMap    map[string]*ScalarProto3 `protobuf:"8"`
   969  	Union         isEnumMessages_Union     `protobuf_oneof:"union"`
   970  }
   971  
   972  var enumMessagesType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(EnumMessages)), Desc: mustMakeMessageDesc("enum-messages.proto", protoreflect.Proto2, `
   973  		dependency: ["enum2.proto", "enum3.proto", "scalar2.proto", "scalar3.proto", "proto2_20180125_92554152/test.proto"]
   974  	`, `
   975  		name: "EnumMessages"
   976  		field: [
   977  			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_ENUM    type_name:".EnumProto2" default_value:"BEEF"},
   978  			{name:"f2"  number:2  label:LABEL_OPTIONAL type:TYPE_ENUM    type_name:".EnumProto3" default_value:"BRAVO"},
   979  			{name:"f3"  number:3  label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".google.golang.org.proto2_20180125.Message"},
   980  			{name:"f4"  number:4  label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".EnumMessages"},
   981  			{name:"f5"  number:5  label:LABEL_REPEATED type:TYPE_ENUM    type_name:".EnumProto2"},
   982  			{name:"f6"  number:6  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".ScalarProto2"},
   983  			{name:"f7"  number:7  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages.F7Entry"},
   984  			{name:"f8"  number:8  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages.F8Entry"},
   985  			{name:"f9"  number:9  label:LABEL_OPTIONAL type:TYPE_ENUM    type_name:".EnumProto2"   oneof_index:0 default_value:"BEEF"},
   986  			{name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_ENUM    type_name:".EnumProto3"   oneof_index:0 default_value:"BRAVO"},
   987  			{name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto2" oneof_index:0},
   988  			{name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto3" oneof_index:0}
   989  		]
   990  		oneof_decl: [{name:"union"}]
   991  		nested_type: [
   992  			{name:"F7Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_ENUM    type_name:".EnumProto3"}]   options:{map_entry:true}},
   993  			{name:"F8Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto3"}] options:{map_entry:true}}
   994  		]
   995  	`, newFileRegistry(
   996  	EnumProto2(0).Descriptor().ParentFile(),
   997  	EnumProto3(0).Descriptor().ParentFile(),
   998  	((*ScalarProto2)(nil)).ProtoReflect().Descriptor().ParentFile(),
   999  	((*ScalarProto3)(nil)).ProtoReflect().Descriptor().ParentFile(),
  1000  	pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message)(nil)).ParentFile(),
  1001  )),
  1002  }
  1003  
  1004  func newFileRegistry(files ...protoreflect.FileDescriptor) *protoregistry.Files {
  1005  	r := new(protoregistry.Files)
  1006  	for _, file := range files {
  1007  		r.RegisterFile(file)
  1008  	}
  1009  	return r
  1010  }
  1011  
  1012  func (m *EnumMessages) ProtoReflect() protoreflect.Message { return enumMessagesType.MessageOf(m) }
  1013  
  1014  func (*EnumMessages) XXX_OneofWrappers() []interface{} {
  1015  	return []interface{}{
  1016  		(*EnumMessages_OneofE2)(nil),
  1017  		(*EnumMessages_OneofE3)(nil),
  1018  		(*EnumMessages_OneofM2)(nil),
  1019  		(*EnumMessages_OneofM3)(nil),
  1020  	}
  1021  }
  1022  
  1023  type (
  1024  	isEnumMessages_Union interface {
  1025  		isEnumMessages_Union()
  1026  	}
  1027  	EnumMessages_OneofE2 struct {
  1028  		OneofE2 EnumProto2 `protobuf:"9"`
  1029  	}
  1030  	EnumMessages_OneofE3 struct {
  1031  		OneofE3 EnumProto3 `protobuf:"10"`
  1032  	}
  1033  	EnumMessages_OneofM2 struct {
  1034  		OneofM2 *ScalarProto2 `protobuf:"11"`
  1035  	}
  1036  	EnumMessages_OneofM3 struct {
  1037  		OneofM3 *ScalarProto3 `protobuf:"12"`
  1038  	}
  1039  )
  1040  
  1041  func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
  1042  func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
  1043  func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
  1044  func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
  1045  
  1046  func TestEnumMessages(t *testing.T) {
  1047  	emptyL := pimpl.Export{}.MessageOf(new(proto2_20180125.Message))
  1048  	emptyM := new(EnumMessages).ProtoReflect()
  1049  	emptyM2 := new(ScalarProto2).ProtoReflect()
  1050  	emptyM3 := new(ScalarProto3).ProtoReflect()
  1051  
  1052  	wantL := pimpl.Export{}.MessageOf(&proto2_20180125.Message{OptionalFloat: proto.Float32(math.E)})
  1053  	wantM := (&EnumMessages{EnumP2: EnumProto2(1234).Enum()}).ProtoReflect()
  1054  	wantM2a := &ScalarProto2{Float32: proto.Float32(math.Pi)}
  1055  	wantM2b := &ScalarProto2{Float32: proto.Float32(math.Phi)}
  1056  	wantM3a := &ScalarProto3{Float32: math.Pi}
  1057  	wantM3b := &ScalarProto3{Float32: math.Ln2}
  1058  
  1059  	wantList5 := getField((&EnumMessages{EnumList: []EnumProto2{333, 222}}).ProtoReflect(), 5)
  1060  	wantList6 := getField((&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).ProtoReflect(), 6)
  1061  
  1062  	wantMap7 := getField((&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).ProtoReflect(), 7)
  1063  	wantMap8 := getField((&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).ProtoReflect(), 8)
  1064  
  1065  	testMessage(t, nil, new(EnumMessages).ProtoReflect(), messageOps{
  1066  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false},
  1067  		getFields{1: VE(0xbeef), 2: VE(1), 3: V(emptyL), 4: V(emptyM), 9: VE(0xbeef), 10: VE(1)},
  1068  
  1069  		// Test singular enums.
  1070  		setFields{1: VE(0xdead), 2: VE(0)},
  1071  		getFields{1: VE(0xdead), 2: VE(0)},
  1072  		hasFields{1: true, 2: true},
  1073  
  1074  		// Test singular messages.
  1075  		messageFieldsMutable{3: messageOps{setFields{109: V(float32(math.E))}}},
  1076  		messageFieldsMutable{4: messageOps{setFields{1: VE(1234)}}},
  1077  		getFields{3: V(wantL), 4: V(wantM)},
  1078  		clearFields{3, 4},
  1079  		hasFields{3: false, 4: false},
  1080  		setFields{3: V(wantL), 4: V(wantM)},
  1081  		hasFields{3: true, 4: true},
  1082  
  1083  		// Test list of enums and messages.
  1084  		listFieldsMutable{
  1085  			5: listOps{
  1086  				appendList{VE(111), VE(222)},
  1087  				setList{0: VE(333)},
  1088  				getList{0: VE(333), 1: VE(222)},
  1089  				lenList(2),
  1090  			},
  1091  			6: listOps{
  1092  				appendMessageList{setFields{4: V(uint32(1e6))}},
  1093  				appendMessageList{setFields{6: V(float32(math.Phi))}},
  1094  				setList{0: V(wantM2a.ProtoReflect())},
  1095  				getList{0: V(wantM2a.ProtoReflect()), 1: V(wantM2b.ProtoReflect())},
  1096  			},
  1097  		},
  1098  		getFields{5: wantList5, 6: wantList6},
  1099  		hasFields{5: true, 6: true},
  1100  		listFields{5: listOps{truncList(0)}},
  1101  		hasFields{5: false, 6: true},
  1102  
  1103  		// Test maps of enums and messages.
  1104  		mapFieldsMutable{
  1105  			7: mapOps{
  1106  				setMap{"one": VE(1), "two": VE(2)},
  1107  				hasMap{"one": true, "two": true, "three": false},
  1108  				lenMap(2),
  1109  			},
  1110  			8: mapOps{
  1111  				messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
  1112  				setMap{"ln2": V(wantM3b.ProtoReflect())},
  1113  				getMap{"pi": V(wantM3a.ProtoReflect()), "ln2": V(wantM3b.ProtoReflect()), "none": V(nil)},
  1114  				lenMap(2),
  1115  			},
  1116  		},
  1117  		getFields{7: wantMap7, 8: wantMap8},
  1118  		hasFields{7: true, 8: true},
  1119  		mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
  1120  		hasFields{7: true, 8: false},
  1121  
  1122  		// Test oneofs of enums and messages.
  1123  		setFields{9: VE(0xdead)},
  1124  		hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
  1125  		setFields{10: VE(0)},
  1126  		hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
  1127  		messageFieldsMutable{11: messageOps{setFields{6: V(float32(math.Pi))}}},
  1128  		getFields{11: V(wantM2a.ProtoReflect())},
  1129  		hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
  1130  		messageFieldsMutable{12: messageOps{setFields{6: V(float32(math.Pi))}}},
  1131  		getFields{12: V(wantM3a.ProtoReflect())},
  1132  		hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
  1133  
  1134  		// Check entire message.
  1135  		rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a.ProtoReflect())},
  1136  		equalMessage{(&EnumMessages{
  1137  			EnumP2:        EnumProto2(0xdead).Enum(),
  1138  			EnumP3:        EnumProto3(0).Enum(),
  1139  			MessageLegacy: &proto2_20180125.Message{OptionalFloat: proto.Float32(math.E)},
  1140  			MessageCycle:  wantM.Interface().(*EnumMessages),
  1141  			MessageList:   []*ScalarProto2{wantM2a, wantM2b},
  1142  			EnumMap:       map[string]EnumProto3{"one": 1, "two": 2},
  1143  			Union:         &EnumMessages_OneofM3{wantM3a},
  1144  		}).ProtoReflect()},
  1145  		clearFields{1, 2, 3, 4, 6, 7, 12},
  1146  		equalMessage{new(EnumMessages).ProtoReflect()},
  1147  	})
  1148  
  1149  	// Test read-only operations on nil message.
  1150  	testMessage(t, nil, (*EnumMessages)(nil).ProtoReflect(), messageOps{
  1151  		hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false},
  1152  		getFields{1: VE(0xbeef), 2: VE(1), 3: V(emptyL), 4: V(emptyM), 9: VE(0xbeef), 10: VE(1), 11: V(emptyM2), 12: V(emptyM3)},
  1153  		listFields{5: {lenList(0)}, 6: {lenList(0)}},
  1154  		mapFields{7: {lenMap(0)}, 8: {lenMap(0)}},
  1155  	})
  1156  }
  1157  
  1158  var cmpOpts = cmp.Options{
  1159  	cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
  1160  		mx := pimpl.Export{}.MessageOf(x).Interface()
  1161  		my := pimpl.Export{}.MessageOf(y).Interface()
  1162  		return proto.Equal(mx, my)
  1163  	}),
  1164  	cmp.Transformer("UnwrapValue", func(pv protoreflect.Value) interface{} {
  1165  		switch v := pv.Interface().(type) {
  1166  		case protoreflect.Message:
  1167  			out := make(map[protoreflect.FieldNumber]protoreflect.Value)
  1168  			v.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
  1169  				out[fd.Number()] = v
  1170  				return true
  1171  			})
  1172  			return out
  1173  		case protoreflect.List:
  1174  			var out []protoreflect.Value
  1175  			for i := 0; i < v.Len(); i++ {
  1176  				out = append(out, v.Get(i))
  1177  			}
  1178  			return out
  1179  		case protoreflect.Map:
  1180  			out := make(map[interface{}]protoreflect.Value)
  1181  			v.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
  1182  				out[k.Interface()] = v
  1183  				return true
  1184  			})
  1185  			return out
  1186  		default:
  1187  			return v
  1188  		}
  1189  	}),
  1190  	cmpopts.EquateNaNs(),
  1191  }
  1192  
  1193  func testMessage(t *testing.T, p path, m protoreflect.Message, tt messageOps) {
  1194  	fieldDescs := m.Descriptor().Fields()
  1195  	oneofDescs := m.Descriptor().Oneofs()
  1196  	for i, op := range tt {
  1197  		p.Push(i)
  1198  		switch op := op.(type) {
  1199  		case equalMessage:
  1200  			if diff := cmp.Diff(V(op.Message), V(m), cmpOpts); diff != "" {
  1201  				t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
  1202  			}
  1203  		case hasFields:
  1204  			got := map[protoreflect.FieldNumber]bool{}
  1205  			want := map[protoreflect.FieldNumber]bool(op)
  1206  			for n := range want {
  1207  				fd := fieldDescs.ByNumber(n)
  1208  				got[n] = m.Has(fd)
  1209  			}
  1210  			if diff := cmp.Diff(want, got); diff != "" {
  1211  				t.Errorf("operation %v, Message.Has mismatch (-want, +got):\n%s", p, diff)
  1212  			}
  1213  		case getFields:
  1214  			got := map[protoreflect.FieldNumber]protoreflect.Value{}
  1215  			want := map[protoreflect.FieldNumber]protoreflect.Value(op)
  1216  			for n := range want {
  1217  				fd := fieldDescs.ByNumber(n)
  1218  				got[n] = m.Get(fd)
  1219  			}
  1220  			if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
  1221  				t.Errorf("operation %v, Message.Get mismatch (-want, +got):\n%s", p, diff)
  1222  			}
  1223  		case setFields:
  1224  			for n, v := range op {
  1225  				fd := fieldDescs.ByNumber(n)
  1226  				m.Set(fd, v)
  1227  			}
  1228  		case clearFields:
  1229  			for _, n := range op {
  1230  				fd := fieldDescs.ByNumber(n)
  1231  				m.Clear(fd)
  1232  			}
  1233  		case whichOneofs:
  1234  			got := map[protoreflect.Name]protoreflect.FieldNumber{}
  1235  			want := map[protoreflect.Name]protoreflect.FieldNumber(op)
  1236  			for s := range want {
  1237  				od := oneofDescs.ByName(s)
  1238  				fd := m.WhichOneof(od)
  1239  				if fd == nil {
  1240  					got[s] = 0
  1241  				} else {
  1242  					got[s] = fd.Number()
  1243  				}
  1244  			}
  1245  			if diff := cmp.Diff(want, got); diff != "" {
  1246  				t.Errorf("operation %v, Message.WhichOneof mismatch (-want, +got):\n%s", p, diff)
  1247  			}
  1248  		case messageFields:
  1249  			for n, tt := range op {
  1250  				p.Push(int(n))
  1251  				fd := fieldDescs.ByNumber(n)
  1252  				testMessage(t, p, m.Get(fd).Message(), tt)
  1253  				p.Pop()
  1254  			}
  1255  		case messageFieldsMutable:
  1256  			for n, tt := range op {
  1257  				p.Push(int(n))
  1258  				fd := fieldDescs.ByNumber(n)
  1259  				testMessage(t, p, m.Mutable(fd).Message(), tt)
  1260  				p.Pop()
  1261  			}
  1262  		case listFields:
  1263  			for n, tt := range op {
  1264  				p.Push(int(n))
  1265  				fd := fieldDescs.ByNumber(n)
  1266  				testLists(t, p, m.Get(fd).List(), tt)
  1267  				p.Pop()
  1268  			}
  1269  		case listFieldsMutable:
  1270  			for n, tt := range op {
  1271  				p.Push(int(n))
  1272  				fd := fieldDescs.ByNumber(n)
  1273  				testLists(t, p, m.Mutable(fd).List(), tt)
  1274  				p.Pop()
  1275  			}
  1276  		case mapFields:
  1277  			for n, tt := range op {
  1278  				p.Push(int(n))
  1279  				fd := fieldDescs.ByNumber(n)
  1280  				testMaps(t, p, m.Get(fd).Map(), tt)
  1281  				p.Pop()
  1282  			}
  1283  		case mapFieldsMutable:
  1284  			for n, tt := range op {
  1285  				p.Push(int(n))
  1286  				fd := fieldDescs.ByNumber(n)
  1287  				testMaps(t, p, m.Mutable(fd).Map(), tt)
  1288  				p.Pop()
  1289  			}
  1290  		case rangeFields:
  1291  			got := map[protoreflect.FieldNumber]protoreflect.Value{}
  1292  			want := map[protoreflect.FieldNumber]protoreflect.Value(op)
  1293  			m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
  1294  				got[fd.Number()] = v
  1295  				return true
  1296  			})
  1297  			if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
  1298  				t.Errorf("operation %v, Message.Range mismatch (-want, +got):\n%s", p, diff)
  1299  			}
  1300  		default:
  1301  			t.Fatalf("operation %v, invalid operation: %T", p, op)
  1302  		}
  1303  		p.Pop()
  1304  	}
  1305  }
  1306  
  1307  func testLists(t *testing.T, p path, v protoreflect.List, tt listOps) {
  1308  	for i, op := range tt {
  1309  		p.Push(i)
  1310  		switch op := op.(type) {
  1311  		case equalList:
  1312  			if diff := cmp.Diff(V(op.List), V(v), cmpOpts); diff != "" {
  1313  				t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
  1314  			}
  1315  		case lenList:
  1316  			if got, want := v.Len(), int(op); got != want {
  1317  				t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
  1318  			}
  1319  		case getList:
  1320  			got := map[int]protoreflect.Value{}
  1321  			want := map[int]protoreflect.Value(op)
  1322  			for n := range want {
  1323  				got[n] = v.Get(n)
  1324  			}
  1325  			if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
  1326  				t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
  1327  			}
  1328  		case setList:
  1329  			for n, e := range op {
  1330  				v.Set(n, e)
  1331  			}
  1332  		case appendList:
  1333  			for _, e := range op {
  1334  				v.Append(e)
  1335  			}
  1336  		case appendMessageList:
  1337  			e := v.NewElement()
  1338  			v.Append(e)
  1339  			testMessage(t, p, e.Message(), messageOps(op))
  1340  		case truncList:
  1341  			v.Truncate(int(op))
  1342  		default:
  1343  			t.Fatalf("operation %v, invalid operation: %T", p, op)
  1344  		}
  1345  		p.Pop()
  1346  	}
  1347  }
  1348  
  1349  func testMaps(t *testing.T, p path, m protoreflect.Map, tt mapOps) {
  1350  	for i, op := range tt {
  1351  		p.Push(i)
  1352  		switch op := op.(type) {
  1353  		case equalMap:
  1354  			if diff := cmp.Diff(V(op.Map), V(m), cmpOpts); diff != "" {
  1355  				t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
  1356  			}
  1357  		case lenMap:
  1358  			if got, want := m.Len(), int(op); got != want {
  1359  				t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
  1360  			}
  1361  		case hasMap:
  1362  			got := map[interface{}]bool{}
  1363  			want := map[interface{}]bool(op)
  1364  			for k := range want {
  1365  				got[k] = m.Has(V(k).MapKey())
  1366  			}
  1367  			if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
  1368  				t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
  1369  			}
  1370  		case getMap:
  1371  			got := map[interface{}]protoreflect.Value{}
  1372  			want := map[interface{}]protoreflect.Value(op)
  1373  			for k := range want {
  1374  				got[k] = m.Get(V(k).MapKey())
  1375  			}
  1376  			if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
  1377  				t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
  1378  			}
  1379  		case setMap:
  1380  			for k, v := range op {
  1381  				m.Set(V(k).MapKey(), v)
  1382  			}
  1383  		case clearMap:
  1384  			for _, k := range op {
  1385  				m.Clear(V(k).MapKey())
  1386  			}
  1387  		case messageMap:
  1388  			for k, tt := range op {
  1389  				mk := V(k).MapKey()
  1390  				if !m.Has(mk) {
  1391  					m.Set(mk, m.NewValue())
  1392  				}
  1393  				testMessage(t, p, m.Get(mk).Message(), tt)
  1394  			}
  1395  		case rangeMap:
  1396  			got := map[interface{}]protoreflect.Value{}
  1397  			want := map[interface{}]protoreflect.Value(op)
  1398  			m.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
  1399  				got[k.Interface()] = v
  1400  				return true
  1401  			})
  1402  			if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
  1403  				t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
  1404  			}
  1405  		default:
  1406  			t.Fatalf("operation %v, invalid operation: %T", p, op)
  1407  		}
  1408  		p.Pop()
  1409  	}
  1410  }
  1411  
  1412  func getField(m protoreflect.Message, n protoreflect.FieldNumber) protoreflect.Value {
  1413  	fd := m.Descriptor().Fields().ByNumber(n)
  1414  	return m.Get(fd)
  1415  }
  1416  
  1417  type path []int
  1418  
  1419  func (p *path) Push(i int) { *p = append(*p, i) }
  1420  func (p *path) Pop()       { *p = (*p)[:len(*p)-1] }
  1421  func (p path) String() string {
  1422  	var ss []string
  1423  	for _, i := range p {
  1424  		ss = append(ss, fmt.Sprint(i))
  1425  	}
  1426  	return strings.Join(ss, ".")
  1427  }
  1428  
  1429  type UnknownFieldsA struct {
  1430  	XXX_unrecognized []byte
  1431  }
  1432  
  1433  var unknownFieldsAType = pimpl.MessageInfo{
  1434  	GoReflectType: reflect.TypeOf(new(UnknownFieldsA)),
  1435  	Desc:          mustMakeMessageDesc("unknown.proto", protoreflect.Proto2, "", `name: "UnknownFieldsA"`, nil),
  1436  }
  1437  
  1438  func (m *UnknownFieldsA) ProtoReflect() protoreflect.Message { return unknownFieldsAType.MessageOf(m) }
  1439  
  1440  type UnknownFieldsB struct {
  1441  	XXX_unrecognized *[]byte
  1442  }
  1443  
  1444  var unknownFieldsBType = pimpl.MessageInfo{
  1445  	GoReflectType: reflect.TypeOf(new(UnknownFieldsB)),
  1446  	Desc:          mustMakeMessageDesc("unknown.proto", protoreflect.Proto2, "", `name: "UnknownFieldsB"`, nil),
  1447  }
  1448  
  1449  func (m *UnknownFieldsB) ProtoReflect() protoreflect.Message { return unknownFieldsBType.MessageOf(m) }
  1450  
  1451  func TestUnknownFields(t *testing.T) {
  1452  	for _, m := range []proto.Message{new(UnknownFieldsA), new(UnknownFieldsB)} {
  1453  		t.Run(reflect.TypeOf(m).Elem().Name(), func(t *testing.T) {
  1454  			want := protopack.Message{
  1455  				protopack.Tag{1, protopack.BytesType}, protopack.String("Hello, world!"),
  1456  			}.Marshal()
  1457  			m.ProtoReflect().SetUnknown(want)
  1458  			got := []byte(m.ProtoReflect().GetUnknown())
  1459  			if diff := cmp.Diff(want, got); diff != "" {
  1460  				t.Errorf("UnknownFields mismatch (-want +got):\n%s", diff)
  1461  			}
  1462  		})
  1463  	}
  1464  }
  1465  
  1466  func TestReset(t *testing.T) {
  1467  	mi := new(testpb.TestAllTypes)
  1468  
  1469  	// ProtoReflect is implemented using a messageState cache.
  1470  	m := mi.ProtoReflect()
  1471  
  1472  	// Reset must not clear the messageState cache.
  1473  	mi.Reset()
  1474  
  1475  	// If Reset accidentally cleared the messageState cache, this panics.
  1476  	m.Descriptor()
  1477  }
  1478  
  1479  func TestIsValid(t *testing.T) {
  1480  	var m *testpb.TestAllTypes
  1481  	if got, want := m.ProtoReflect().IsValid(), false; got != want {
  1482  		t.Errorf("((*M)(nil)).ProtoReflect().IsValid() = %v, want %v", got, want)
  1483  	}
  1484  	m = &testpb.TestAllTypes{}
  1485  	if got, want := m.ProtoReflect().IsValid(), true; got != want {
  1486  		t.Errorf("(&M{}).ProtoReflect().IsValid() = %v, want %v", got, want)
  1487  	}
  1488  }
  1489  
  1490  // The MessageState implementation makes the assumption that when a
  1491  // concrete message is unsafe casted as a *MessageState, the Go GC does
  1492  // not reclaim the memory for the remainder of the concrete message.
  1493  func TestUnsafeAssumptions(t *testing.T) {
  1494  	if !pimpl.UnsafeEnabled {
  1495  		t.Skip()
  1496  	}
  1497  
  1498  	var wg sync.WaitGroup
  1499  	for i := 0; i < 10; i++ {
  1500  		wg.Add(1)
  1501  		go func() {
  1502  			var ms [10]protoreflect.Message
  1503  
  1504  			// Store the message only in its reflective form.
  1505  			// Trigger the GC after each iteration.
  1506  			for j := 0; j < 10; j++ {
  1507  				ms[j] = (&testpb.TestAllTypes{
  1508  					OptionalInt32: proto.Int32(int32(j)),
  1509  					OptionalFloat: proto.Float32(float32(j)),
  1510  					RepeatedInt32: []int32{int32(j)},
  1511  					RepeatedFloat: []float32{float32(j)},
  1512  					DefaultInt32:  proto.Int32(int32(j)),
  1513  					DefaultFloat:  proto.Float32(float32(j)),
  1514  				}).ProtoReflect()
  1515  				runtime.GC()
  1516  			}
  1517  
  1518  			// Convert the reflective form back into a concrete form.
  1519  			// Verify that the values written previously are still the same.
  1520  			for j := 0; j < 10; j++ {
  1521  				switch m := ms[j].Interface().(*testpb.TestAllTypes); {
  1522  				case m.GetOptionalInt32() != int32(j):
  1523  				case m.GetOptionalFloat() != float32(j):
  1524  				case m.GetRepeatedInt32()[0] != int32(j):
  1525  				case m.GetRepeatedFloat()[0] != float32(j):
  1526  				case m.GetDefaultInt32() != int32(j):
  1527  				case m.GetDefaultFloat() != float32(j):
  1528  				default:
  1529  					continue
  1530  				}
  1531  				t.Error("memory corrupted detected")
  1532  			}
  1533  			defer wg.Done()
  1534  		}()
  1535  	}
  1536  	wg.Wait()
  1537  }
  1538  
  1539  func BenchmarkName(b *testing.B) {
  1540  	var sink protoreflect.FullName
  1541  	b.Run("Value", func(b *testing.B) {
  1542  		b.ReportAllocs()
  1543  		m := new(descriptorpb.FileDescriptorProto)
  1544  		for i := 0; i < b.N; i++ {
  1545  			sink = m.ProtoReflect().Descriptor().FullName()
  1546  		}
  1547  	})
  1548  	b.Run("Nil", func(b *testing.B) {
  1549  		b.ReportAllocs()
  1550  		m := (*descriptorpb.FileDescriptorProto)(nil)
  1551  		for i := 0; i < b.N; i++ {
  1552  			sink = m.ProtoReflect().Descriptor().FullName()
  1553  		}
  1554  	})
  1555  	runtime.KeepAlive(sink)
  1556  }
  1557  
  1558  func BenchmarkReflect(b *testing.B) {
  1559  	m := new(testpb.TestAllTypes).ProtoReflect()
  1560  	fds := m.Descriptor().Fields()
  1561  	vs := make([]protoreflect.Value, fds.Len())
  1562  	for i := range vs {
  1563  		vs[i] = m.NewField(fds.Get(i))
  1564  	}
  1565  
  1566  	b.Run("Has", func(b *testing.B) {
  1567  		b.ReportAllocs()
  1568  		for i := 0; i < b.N; i++ {
  1569  			for j := 0; j < fds.Len(); j++ {
  1570  				m.Has(fds.Get(j))
  1571  			}
  1572  		}
  1573  	})
  1574  	b.Run("Get", func(b *testing.B) {
  1575  		b.ReportAllocs()
  1576  		for i := 0; i < b.N; i++ {
  1577  			for j := 0; j < fds.Len(); j++ {
  1578  				m.Get(fds.Get(j))
  1579  			}
  1580  		}
  1581  	})
  1582  	b.Run("Set", func(b *testing.B) {
  1583  		b.ReportAllocs()
  1584  		for i := 0; i < b.N; i++ {
  1585  			for j := 0; j < fds.Len(); j++ {
  1586  				m.Set(fds.Get(j), vs[j])
  1587  			}
  1588  		}
  1589  	})
  1590  	b.Run("Clear", func(b *testing.B) {
  1591  		b.ReportAllocs()
  1592  		for i := 0; i < b.N; i++ {
  1593  			for j := 0; j < fds.Len(); j++ {
  1594  				m.Clear(fds.Get(j))
  1595  			}
  1596  		}
  1597  	})
  1598  	b.Run("Range", func(b *testing.B) {
  1599  		b.ReportAllocs()
  1600  		for i := 0; i < b.N; i++ {
  1601  			m.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
  1602  				return true
  1603  			})
  1604  		}
  1605  	})
  1606  }
  1607  

View as plain text