1// Copyright 2019 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 prototest exercises protobuf reflection. 6package prototest 7 8import ( 9 "bytes" 10 "fmt" 11 "math" 12 "reflect" 13 "sort" 14 "strings" 15 "testing" 16 17 "google.golang.org/protobuf/encoding/prototext" 18 "google.golang.org/protobuf/encoding/protowire" 19 "google.golang.org/protobuf/proto" 20 "google.golang.org/protobuf/reflect/protoreflect" 21 "google.golang.org/protobuf/reflect/protoregistry" 22) 23 24// TODO: Test invalid field descriptors or oneof descriptors. 25// TODO: This should test the functionality that can be provided by fast-paths. 26 27// Message tests a message implementation. 28type Message struct { 29 // Resolver is used to determine the list of extension fields to test with. 30 // If nil, this defaults to using protoregistry.GlobalTypes. 31 Resolver interface { 32 FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) 33 FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) 34 RangeExtensionsByMessage(message protoreflect.FullName, f func(protoreflect.ExtensionType) bool) 35 } 36} 37 38// Test performs tests on a MessageType implementation. 39func (test Message) Test(t testing.TB, mt protoreflect.MessageType) { 40 testType(t, mt) 41 42 md := mt.Descriptor() 43 m1 := mt.New() 44 for i := 0; i < md.Fields().Len(); i++ { 45 fd := md.Fields().Get(i) 46 testField(t, m1, fd) 47 } 48 if test.Resolver == nil { 49 test.Resolver = protoregistry.GlobalTypes 50 } 51 var extTypes []protoreflect.ExtensionType 52 test.Resolver.RangeExtensionsByMessage(md.FullName(), func(e protoreflect.ExtensionType) bool { 53 extTypes = append(extTypes, e) 54 return true 55 }) 56 for _, xt := range extTypes { 57 testField(t, m1, xt.TypeDescriptor()) 58 } 59 for i := 0; i < md.Oneofs().Len(); i++ { 60 testOneof(t, m1, md.Oneofs().Get(i)) 61 } 62 testUnknown(t, m1) 63 64 // Test round-trip marshal/unmarshal. 65 m2 := mt.New().Interface() 66 populateMessage(m2.ProtoReflect(), 1, nil) 67 for _, xt := range extTypes { 68 m2.ProtoReflect().Set(xt.TypeDescriptor(), newValue(m2.ProtoReflect(), xt.TypeDescriptor(), 1, nil)) 69 } 70 b, err := proto.MarshalOptions{ 71 AllowPartial: true, 72 }.Marshal(m2) 73 if err != nil { 74 t.Errorf("Marshal() = %v, want nil\n%v", err, prototext.Format(m2)) 75 } 76 m3 := mt.New().Interface() 77 if err := (proto.UnmarshalOptions{ 78 AllowPartial: true, 79 Resolver: test.Resolver, 80 }.Unmarshal(b, m3)); err != nil { 81 t.Errorf("Unmarshal() = %v, want nil\n%v", err, prototext.Format(m2)) 82 } 83 if !proto.Equal(m2, m3) { 84 t.Errorf("round-trip marshal/unmarshal did not preserve message\nOriginal:\n%v\nNew:\n%v", prototext.Format(m2), prototext.Format(m3)) 85 } 86} 87 88func testType(t testing.TB, mt protoreflect.MessageType) { 89 m := mt.New().Interface() 90 want := reflect.TypeOf(m) 91 if got := reflect.TypeOf(m.ProtoReflect().Interface()); got != want { 92 t.Errorf("type mismatch: reflect.TypeOf(m) != reflect.TypeOf(m.ProtoReflect().Interface()): %v != %v", got, want) 93 } 94 if got := reflect.TypeOf(m.ProtoReflect().New().Interface()); got != want { 95 t.Errorf("type mismatch: reflect.TypeOf(m) != reflect.TypeOf(m.ProtoReflect().New().Interface()): %v != %v", got, want) 96 } 97 if got := reflect.TypeOf(m.ProtoReflect().Type().Zero().Interface()); got != want { 98 t.Errorf("type mismatch: reflect.TypeOf(m) != reflect.TypeOf(m.ProtoReflect().Type().Zero().Interface()): %v != %v", got, want) 99 } 100 if mt, ok := mt.(protoreflect.MessageFieldTypes); ok { 101 testFieldTypes(t, mt) 102 } 103} 104 105func testFieldTypes(t testing.TB, mt protoreflect.MessageFieldTypes) { 106 descName := func(d protoreflect.Descriptor) protoreflect.FullName { 107 if d == nil { 108 return "<nil>" 109 } 110 return d.FullName() 111 } 112 typeName := func(mt protoreflect.MessageType) protoreflect.FullName { 113 if mt == nil { 114 return "<nil>" 115 } 116 return mt.Descriptor().FullName() 117 } 118 adjustExpr := func(idx int, expr string) string { 119 expr = strings.Replace(expr, "fd.", "md.Fields().Get(i).", -1) 120 expr = strings.Replace(expr, "(fd)", "(md.Fields().Get(i))", -1) 121 expr = strings.Replace(expr, "mti.", "mt.Message(i).", -1) 122 expr = strings.Replace(expr, "(i)", fmt.Sprintf("(%d)", idx), -1) 123 return expr 124 } 125 checkEnumDesc := func(idx int, gotExpr, wantExpr string, got, want protoreflect.EnumDescriptor) { 126 if got != want { 127 t.Errorf("descriptor mismatch: %v != %v: %v != %v", adjustExpr(idx, gotExpr), adjustExpr(idx, wantExpr), descName(got), descName(want)) 128 } 129 } 130 checkMessageDesc := func(idx int, gotExpr, wantExpr string, got, want protoreflect.MessageDescriptor) { 131 if got != want { 132 t.Errorf("descriptor mismatch: %v != %v: %v != %v", adjustExpr(idx, gotExpr), adjustExpr(idx, wantExpr), descName(got), descName(want)) 133 } 134 } 135 checkMessageType := func(idx int, gotExpr, wantExpr string, got, want protoreflect.MessageType) { 136 if got != want { 137 t.Errorf("type mismatch: %v != %v: %v != %v", adjustExpr(idx, gotExpr), adjustExpr(idx, wantExpr), typeName(got), typeName(want)) 138 } 139 } 140 141 fds := mt.Descriptor().Fields() 142 m := mt.New() 143 for i := 0; i < fds.Len(); i++ { 144 fd := fds.Get(i) 145 switch { 146 case fd.IsList(): 147 if fd.Enum() != nil { 148 checkEnumDesc(i, 149 "mt.Enum(i).Descriptor()", "fd.Enum()", 150 mt.Enum(i).Descriptor(), fd.Enum()) 151 } 152 if fd.Message() != nil { 153 checkMessageDesc(i, 154 "mt.Message(i).Descriptor()", "fd.Message()", 155 mt.Message(i).Descriptor(), fd.Message()) 156 checkMessageType(i, 157 "mt.Message(i)", "m.NewField(fd).List().NewElement().Message().Type()", 158 mt.Message(i), m.NewField(fd).List().NewElement().Message().Type()) 159 } 160 case fd.IsMap(): 161 mti := mt.Message(i) 162 if m := mti.New(); m != nil { 163 checkMessageDesc(i, 164 "m.Descriptor()", "fd.Message()", 165 m.Descriptor(), fd.Message()) 166 } 167 if m := mti.Zero(); m != nil { 168 checkMessageDesc(i, 169 "m.Descriptor()", "fd.Message()", 170 m.Descriptor(), fd.Message()) 171 } 172 checkMessageDesc(i, 173 "mti.Descriptor()", "fd.Message()", 174 mti.Descriptor(), fd.Message()) 175 if mti := mti.(protoreflect.MessageFieldTypes); mti != nil { 176 if fd.MapValue().Enum() != nil { 177 checkEnumDesc(i, 178 "mti.Enum(fd.MapValue().Index()).Descriptor()", "fd.MapValue().Enum()", 179 mti.Enum(fd.MapValue().Index()).Descriptor(), fd.MapValue().Enum()) 180 } 181 if fd.MapValue().Message() != nil { 182 checkMessageDesc(i, 183 "mti.Message(fd.MapValue().Index()).Descriptor()", "fd.MapValue().Message()", 184 mti.Message(fd.MapValue().Index()).Descriptor(), fd.MapValue().Message()) 185 checkMessageType(i, 186 "mti.Message(fd.MapValue().Index())", "m.NewField(fd).Map().NewValue().Message().Type()", 187 mti.Message(fd.MapValue().Index()), m.NewField(fd).Map().NewValue().Message().Type()) 188 } 189 } 190 default: 191 if fd.Enum() != nil { 192 checkEnumDesc(i, 193 "mt.Enum(i).Descriptor()", "fd.Enum()", 194 mt.Enum(i).Descriptor(), fd.Enum()) 195 } 196 if fd.Message() != nil { 197 checkMessageDesc(i, 198 "mt.Message(i).Descriptor()", "fd.Message()", 199 mt.Message(i).Descriptor(), fd.Message()) 200 checkMessageType(i, 201 "mt.Message(i)", "m.NewField(fd).Message().Type()", 202 mt.Message(i), m.NewField(fd).Message().Type()) 203 } 204 } 205 } 206} 207 208// testField exercises set/get/has/clear of a field. 209func testField(t testing.TB, m protoreflect.Message, fd protoreflect.FieldDescriptor) { 210 name := fd.FullName() 211 num := fd.Number() 212 213 switch { 214 case fd.IsList(): 215 testFieldList(t, m, fd) 216 case fd.IsMap(): 217 testFieldMap(t, m, fd) 218 case fd.Message() != nil: 219 default: 220 if got, want := m.NewField(fd), fd.Default(); !valueEqual(got, want) { 221 t.Errorf("Message.NewField(%v) = %v, want default value %v", name, formatValue(got), formatValue(want)) 222 } 223 if fd.Kind() == protoreflect.FloatKind || fd.Kind() == protoreflect.DoubleKind { 224 testFieldFloat(t, m, fd) 225 } 226 } 227 228 // Set to a non-zero value, the zero value, different non-zero values. 229 for _, n := range []seed{1, 0, minVal, maxVal} { 230 v := newValue(m, fd, n, nil) 231 m.Set(fd, v) 232 wantHas := true 233 if n == 0 { 234 if fd.Syntax() == protoreflect.Proto3 && fd.Message() == nil { 235 wantHas = false 236 } 237 if fd.IsExtension() { 238 wantHas = true 239 } 240 if fd.Cardinality() == protoreflect.Repeated { 241 wantHas = false 242 } 243 if fd.ContainingOneof() != nil { 244 wantHas = true 245 } 246 } 247 if fd.Syntax() == protoreflect.Proto3 && fd.Cardinality() != protoreflect.Repeated && fd.ContainingOneof() == nil && fd.Kind() == protoreflect.EnumKind && v.Enum() == 0 { 248 wantHas = false 249 } 250 if got, want := m.Has(fd), wantHas; got != want { 251 t.Errorf("after setting %q to %v:\nMessage.Has(%v) = %v, want %v", name, formatValue(v), num, got, want) 252 } 253 if got, want := m.Get(fd), v; !valueEqual(got, want) { 254 t.Errorf("after setting %q:\nMessage.Get(%v) = %v, want %v", name, num, formatValue(got), formatValue(want)) 255 } 256 found := false 257 m.Range(func(d protoreflect.FieldDescriptor, got protoreflect.Value) bool { 258 if fd != d { 259 return true 260 } 261 found = true 262 if want := v; !valueEqual(got, want) { 263 t.Errorf("after setting %q:\nMessage.Range got value %v, want %v", name, formatValue(got), formatValue(want)) 264 } 265 return true 266 }) 267 if got, want := wantHas, found; got != want { 268 t.Errorf("after setting %q:\nMessageRange saw field: %v, want %v", name, got, want) 269 } 270 } 271 272 m.Clear(fd) 273 if got, want := m.Has(fd), false; got != want { 274 t.Errorf("after clearing %q:\nMessage.Has(%v) = %v, want %v", name, num, got, want) 275 } 276 switch { 277 case fd.IsList(): 278 if got := m.Get(fd); got.List().Len() != 0 { 279 t.Errorf("after clearing %q:\nMessage.Get(%v) = %v, want empty list", name, num, formatValue(got)) 280 } 281 case fd.IsMap(): 282 if got := m.Get(fd); got.Map().Len() != 0 { 283 t.Errorf("after clearing %q:\nMessage.Get(%v) = %v, want empty map", name, num, formatValue(got)) 284 } 285 case fd.Message() == nil: 286 if got, want := m.Get(fd), fd.Default(); !valueEqual(got, want) { 287 t.Errorf("after clearing %q:\nMessage.Get(%v) = %v, want default %v", name, num, formatValue(got), formatValue(want)) 288 } 289 } 290 291 // Set to the default value. 292 switch { 293 case fd.IsList() || fd.IsMap(): 294 m.Set(fd, m.Mutable(fd)) 295 if got, want := m.Has(fd), (fd.IsExtension() && fd.Cardinality() != protoreflect.Repeated) || fd.ContainingOneof() != nil; got != want { 296 t.Errorf("after setting %q to default:\nMessage.Has(%v) = %v, want %v", name, num, got, want) 297 } 298 case fd.Message() == nil: 299 m.Set(fd, m.Get(fd)) 300 if got, want := m.Get(fd), fd.Default(); !valueEqual(got, want) { 301 t.Errorf("after setting %q to default:\nMessage.Get(%v) = %v, want default %v", name, num, formatValue(got), formatValue(want)) 302 } 303 } 304 m.Clear(fd) 305 306 // Set to the wrong type. 307 v := protoreflect.ValueOfString("") 308 if fd.Kind() == protoreflect.StringKind { 309 v = protoreflect.ValueOfInt32(0) 310 } 311 if !panics(func() { 312 m.Set(fd, v) 313 }) { 314 t.Errorf("setting %v to %T succeeds, want panic", name, v.Interface()) 315 } 316} 317 318// testFieldMap tests set/get/has/clear of entries in a map field. 319func testFieldMap(t testing.TB, m protoreflect.Message, fd protoreflect.FieldDescriptor) { 320 name := fd.FullName() 321 num := fd.Number() 322 323 // New values. 324 m.Clear(fd) // start with an empty map 325 mapv := m.Get(fd).Map() 326 if mapv.IsValid() { 327 t.Errorf("after clearing field: message.Get(%v).IsValid() = true, want false", name) 328 } 329 if got, want := mapv.NewValue(), newMapValue(fd, mapv, 0, nil); !valueEqual(got, want) { 330 t.Errorf("message.Get(%v).NewValue() = %v, want %v", name, formatValue(got), formatValue(want)) 331 } 332 if !panics(func() { 333 m.Set(fd, protoreflect.ValueOfMap(mapv)) 334 }) { 335 t.Errorf("message.Set(%v, <invalid>) does not panic", name) 336 } 337 if !panics(func() { 338 mapv.Set(newMapKey(fd, 0), newMapValue(fd, mapv, 0, nil)) 339 }) { 340 t.Errorf("message.Get(%v).Set(...) of invalid map does not panic", name) 341 } 342 mapv = m.Mutable(fd).Map() // mutable map 343 if !mapv.IsValid() { 344 t.Errorf("message.Mutable(%v).IsValid() = false, want true", name) 345 } 346 if got, want := mapv.NewValue(), newMapValue(fd, mapv, 0, nil); !valueEqual(got, want) { 347 t.Errorf("message.Mutable(%v).NewValue() = %v, want %v", name, formatValue(got), formatValue(want)) 348 } 349 350 // Add values. 351 want := make(testMap) 352 for i, n := range []seed{1, 0, minVal, maxVal} { 353 if got, want := m.Has(fd), i > 0; got != want { 354 t.Errorf("after inserting %d elements to %q:\nMessage.Has(%v) = %v, want %v", i, name, num, got, want) 355 } 356 357 k := newMapKey(fd, n) 358 v := newMapValue(fd, mapv, n, nil) 359 mapv.Set(k, v) 360 want.Set(k, v) 361 if got, want := m.Get(fd), protoreflect.ValueOfMap(want); !valueEqual(got, want) { 362 t.Errorf("after inserting %d elements to %q:\nMessage.Get(%v) = %v, want %v", i, name, num, formatValue(got), formatValue(want)) 363 } 364 } 365 366 // Set values. 367 want.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { 368 nv := newMapValue(fd, mapv, 10, nil) 369 mapv.Set(k, nv) 370 want.Set(k, nv) 371 if got, want := m.Get(fd), protoreflect.ValueOfMap(want); !valueEqual(got, want) { 372 t.Errorf("after setting element %v of %q:\nMessage.Get(%v) = %v, want %v", formatValue(k.Value()), name, num, formatValue(got), formatValue(want)) 373 } 374 return true 375 }) 376 377 // Clear values. 378 want.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { 379 mapv.Clear(k) 380 want.Clear(k) 381 if got, want := m.Has(fd), want.Len() > 0; got != want { 382 t.Errorf("after clearing elements of %q:\nMessage.Has(%v) = %v, want %v", name, num, got, want) 383 } 384 if got, want := m.Get(fd), protoreflect.ValueOfMap(want); !valueEqual(got, want) { 385 t.Errorf("after clearing elements of %q:\nMessage.Get(%v) = %v, want %v", name, num, formatValue(got), formatValue(want)) 386 } 387 return true 388 }) 389 if mapv := m.Get(fd).Map(); mapv.IsValid() { 390 t.Errorf("after clearing all elements: message.Get(%v).IsValid() = true, want false %v", name, formatValue(protoreflect.ValueOfMap(mapv))) 391 } 392 393 // Non-existent map keys. 394 missingKey := newMapKey(fd, 1) 395 if got, want := mapv.Has(missingKey), false; got != want { 396 t.Errorf("non-existent map key in %q: Map.Has(%v) = %v, want %v", name, formatValue(missingKey.Value()), got, want) 397 } 398 if got, want := mapv.Get(missingKey).IsValid(), false; got != want { 399 t.Errorf("non-existent map key in %q: Map.Get(%v).IsValid() = %v, want %v", name, formatValue(missingKey.Value()), got, want) 400 } 401 mapv.Clear(missingKey) // noop 402 403 // Mutable. 404 if fd.MapValue().Message() == nil { 405 if !panics(func() { 406 mapv.Mutable(newMapKey(fd, 1)) 407 }) { 408 t.Errorf("Mutable on %q succeeds, want panic", name) 409 } 410 } else { 411 k := newMapKey(fd, 1) 412 v := mapv.Mutable(k) 413 if got, want := mapv.Len(), 1; got != want { 414 t.Errorf("after Mutable on %q, Map.Len() = %v, want %v", name, got, want) 415 } 416 populateMessage(v.Message(), 1, nil) 417 if !valueEqual(mapv.Get(k), v) { 418 t.Errorf("after Mutable on %q, changing new mutable value does not change map entry", name) 419 } 420 mapv.Clear(k) 421 } 422} 423 424type testMap map[interface{}]protoreflect.Value 425 426func (m testMap) Get(k protoreflect.MapKey) protoreflect.Value { return m[k.Interface()] } 427func (m testMap) Set(k protoreflect.MapKey, v protoreflect.Value) { m[k.Interface()] = v } 428func (m testMap) Has(k protoreflect.MapKey) bool { return m.Get(k).IsValid() } 429func (m testMap) Clear(k protoreflect.MapKey) { delete(m, k.Interface()) } 430func (m testMap) Mutable(k protoreflect.MapKey) protoreflect.Value { panic("unimplemented") } 431func (m testMap) Len() int { return len(m) } 432func (m testMap) NewValue() protoreflect.Value { panic("unimplemented") } 433func (m testMap) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { 434 for k, v := range m { 435 if !f(protoreflect.ValueOf(k).MapKey(), v) { 436 return 437 } 438 } 439} 440func (m testMap) IsValid() bool { return true } 441 442// testFieldList exercises set/get/append/truncate of values in a list. 443func testFieldList(t testing.TB, m protoreflect.Message, fd protoreflect.FieldDescriptor) { 444 name := fd.FullName() 445 num := fd.Number() 446 447 m.Clear(fd) // start with an empty list 448 list := m.Get(fd).List() 449 if list.IsValid() { 450 t.Errorf("message.Get(%v).IsValid() = true, want false", name) 451 } 452 if !panics(func() { 453 m.Set(fd, protoreflect.ValueOfList(list)) 454 }) { 455 t.Errorf("message.Set(%v, <invalid>) does not panic", name) 456 } 457 if !panics(func() { 458 list.Append(newListElement(fd, list, 0, nil)) 459 }) { 460 t.Errorf("message.Get(%v).Append(...) of invalid list does not panic", name) 461 } 462 if got, want := list.NewElement(), newListElement(fd, list, 0, nil); !valueEqual(got, want) { 463 t.Errorf("message.Get(%v).NewElement() = %v, want %v", name, formatValue(got), formatValue(want)) 464 } 465 list = m.Mutable(fd).List() // mutable list 466 if !list.IsValid() { 467 t.Errorf("message.Get(%v).IsValid() = false, want true", name) 468 } 469 if got, want := list.NewElement(), newListElement(fd, list, 0, nil); !valueEqual(got, want) { 470 t.Errorf("message.Mutable(%v).NewElement() = %v, want %v", name, formatValue(got), formatValue(want)) 471 } 472 473 // Append values. 474 var want protoreflect.List = &testList{} 475 for i, n := range []seed{1, 0, minVal, maxVal} { 476 if got, want := m.Has(fd), i > 0; got != want { 477 t.Errorf("after appending %d elements to %q:\nMessage.Has(%v) = %v, want %v", i, name, num, got, want) 478 } 479 v := newListElement(fd, list, n, nil) 480 want.Append(v) 481 list.Append(v) 482 483 if got, want := m.Get(fd), protoreflect.ValueOfList(want); !valueEqual(got, want) { 484 t.Errorf("after appending %d elements to %q:\nMessage.Get(%v) = %v, want %v", i+1, name, num, formatValue(got), formatValue(want)) 485 } 486 } 487 488 // Set values. 489 for i := 0; i < want.Len(); i++ { 490 v := newListElement(fd, list, seed(i+10), nil) 491 want.Set(i, v) 492 list.Set(i, v) 493 if got, want := m.Get(fd), protoreflect.ValueOfList(want); !valueEqual(got, want) { 494 t.Errorf("after setting element %d of %q:\nMessage.Get(%v) = %v, want %v", i, name, num, formatValue(got), formatValue(want)) 495 } 496 } 497 498 // Truncate. 499 for want.Len() > 0 { 500 n := want.Len() - 1 501 want.Truncate(n) 502 list.Truncate(n) 503 if got, want := m.Has(fd), want.Len() > 0; got != want { 504 t.Errorf("after truncating %q to %d:\nMessage.Has(%v) = %v, want %v", name, n, num, got, want) 505 } 506 if got, want := m.Get(fd), protoreflect.ValueOfList(want); !valueEqual(got, want) { 507 t.Errorf("after truncating %q to %d:\nMessage.Get(%v) = %v, want %v", name, n, num, formatValue(got), formatValue(want)) 508 } 509 } 510 511 // AppendMutable. 512 if fd.Message() == nil { 513 if !panics(func() { 514 list.AppendMutable() 515 }) { 516 t.Errorf("AppendMutable on %q succeeds, want panic", name) 517 } 518 } else { 519 v := list.AppendMutable() 520 if got, want := list.Len(), 1; got != want { 521 t.Errorf("after AppendMutable on %q, list.Len() = %v, want %v", name, got, want) 522 } 523 populateMessage(v.Message(), 1, nil) 524 if !valueEqual(list.Get(0), v) { 525 t.Errorf("after AppendMutable on %q, changing new mutable value does not change list item 0", name) 526 } 527 want.Truncate(0) 528 } 529} 530 531type testList struct { 532 a []protoreflect.Value 533} 534 535func (l *testList) Append(v protoreflect.Value) { l.a = append(l.a, v) } 536func (l *testList) AppendMutable() protoreflect.Value { panic("unimplemented") } 537func (l *testList) Get(n int) protoreflect.Value { return l.a[n] } 538func (l *testList) Len() int { return len(l.a) } 539func (l *testList) Set(n int, v protoreflect.Value) { l.a[n] = v } 540func (l *testList) Truncate(n int) { l.a = l.a[:n] } 541func (l *testList) NewElement() protoreflect.Value { panic("unimplemented") } 542func (l *testList) IsValid() bool { return true } 543 544// testFieldFloat exercises some interesting floating-point scalar field values. 545func testFieldFloat(t testing.TB, m protoreflect.Message, fd protoreflect.FieldDescriptor) { 546 name := fd.FullName() 547 num := fd.Number() 548 549 for _, v := range []float64{math.Inf(-1), math.Inf(1), math.NaN(), math.Copysign(0, -1)} { 550 var val protoreflect.Value 551 if fd.Kind() == protoreflect.FloatKind { 552 val = protoreflect.ValueOfFloat32(float32(v)) 553 } else { 554 val = protoreflect.ValueOfFloat64(float64(v)) 555 } 556 m.Set(fd, val) 557 // Note that Has is true for -0. 558 if got, want := m.Has(fd), true; got != want { 559 t.Errorf("after setting %v to %v: Message.Has(%v) = %v, want %v", name, v, num, got, want) 560 } 561 if got, want := m.Get(fd), val; !valueEqual(got, want) { 562 t.Errorf("after setting %v: Message.Get(%v) = %v, want %v", name, num, formatValue(got), formatValue(want)) 563 } 564 } 565} 566 567// testOneof tests the behavior of fields in a oneof. 568func testOneof(t testing.TB, m protoreflect.Message, od protoreflect.OneofDescriptor) { 569 for _, mutable := range []bool{false, true} { 570 for i := 0; i < od.Fields().Len(); i++ { 571 fda := od.Fields().Get(i) 572 if mutable { 573 // Set fields by requesting a mutable reference. 574 if !fda.IsMap() && !fda.IsList() && fda.Message() == nil { 575 continue 576 } 577 _ = m.Mutable(fda) 578 } else { 579 // Set fields explicitly. 580 m.Set(fda, newValue(m, fda, 1, nil)) 581 } 582 if got, want := m.WhichOneof(od), fda; got != want { 583 t.Errorf("after setting oneof field %q:\nWhichOneof(%q) = %v, want %v", fda.FullName(), fda.Name(), got, want) 584 } 585 for j := 0; j < od.Fields().Len(); j++ { 586 fdb := od.Fields().Get(j) 587 if got, want := m.Has(fdb), i == j; got != want { 588 t.Errorf("after setting oneof field %q:\nGet(%q) = %v, want %v", fda.FullName(), fdb.FullName(), got, want) 589 } 590 } 591 } 592 } 593} 594 595// testUnknown tests the behavior of unknown fields. 596func testUnknown(t testing.TB, m protoreflect.Message) { 597 var b []byte 598 b = protowire.AppendTag(b, 1000, protowire.VarintType) 599 b = protowire.AppendVarint(b, 1001) 600 m.SetUnknown(protoreflect.RawFields(b)) 601 if got, want := []byte(m.GetUnknown()), b; !bytes.Equal(got, want) { 602 t.Errorf("after setting unknown fields:\nGetUnknown() = %v, want %v", got, want) 603 } 604} 605 606func formatValue(v protoreflect.Value) string { 607 switch v := v.Interface().(type) { 608 case protoreflect.List: 609 var buf bytes.Buffer 610 buf.WriteString("list[") 611 for i := 0; i < v.Len(); i++ { 612 if i > 0 { 613 buf.WriteString(" ") 614 } 615 buf.WriteString(formatValue(v.Get(i))) 616 } 617 buf.WriteString("]") 618 return buf.String() 619 case protoreflect.Map: 620 var buf bytes.Buffer 621 buf.WriteString("map[") 622 var keys []protoreflect.MapKey 623 v.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { 624 keys = append(keys, k) 625 return true 626 }) 627 sort.Slice(keys, func(i, j int) bool { 628 return keys[i].String() < keys[j].String() 629 }) 630 for i, k := range keys { 631 if i > 0 { 632 buf.WriteString(" ") 633 } 634 buf.WriteString(formatValue(k.Value())) 635 buf.WriteString(":") 636 buf.WriteString(formatValue(v.Get(k))) 637 } 638 buf.WriteString("]") 639 return buf.String() 640 case protoreflect.Message: 641 b, err := prototext.Marshal(v.Interface()) 642 if err != nil { 643 return fmt.Sprintf("<%v>", err) 644 } 645 return fmt.Sprintf("%v{%s}", v.Descriptor().FullName(), b) 646 case string: 647 return fmt.Sprintf("%q", v) 648 default: 649 return fmt.Sprint(v) 650 } 651} 652 653func valueEqual(a, b protoreflect.Value) bool { 654 ai, bi := a.Interface(), b.Interface() 655 switch ai.(type) { 656 case protoreflect.Message: 657 return proto.Equal( 658 a.Message().Interface(), 659 b.Message().Interface(), 660 ) 661 case protoreflect.List: 662 lista, listb := a.List(), b.List() 663 if lista.Len() != listb.Len() { 664 return false 665 } 666 for i := 0; i < lista.Len(); i++ { 667 if !valueEqual(lista.Get(i), listb.Get(i)) { 668 return false 669 } 670 } 671 return true 672 case protoreflect.Map: 673 mapa, mapb := a.Map(), b.Map() 674 if mapa.Len() != mapb.Len() { 675 return false 676 } 677 equal := true 678 mapa.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { 679 if !valueEqual(v, mapb.Get(k)) { 680 equal = false 681 return false 682 } 683 return true 684 }) 685 return equal 686 case []byte: 687 return bytes.Equal(a.Bytes(), b.Bytes()) 688 case float32: 689 // NaNs are equal, but must be the same NaN. 690 return math.Float32bits(ai.(float32)) == math.Float32bits(bi.(float32)) 691 case float64: 692 // NaNs are equal, but must be the same NaN. 693 return math.Float64bits(ai.(float64)) == math.Float64bits(bi.(float64)) 694 default: 695 return ai == bi 696 } 697} 698 699// A seed is used to vary the content of a value. 700// 701// A seed of 0 is the zero value. Messages do not have a zero-value; a 0-seeded messages 702// is unpopulated. 703// 704// A seed of minVal or maxVal is the least or greatest value of the value type. 705type seed int 706 707const ( 708 minVal seed = -1 709 maxVal seed = -2 710) 711 712// newSeed creates new seed values from a base, for example to create seeds for the 713// elements in a list. If the input seed is minVal or maxVal, so is the output. 714func newSeed(n seed, adjust ...int) seed { 715 switch n { 716 case minVal, maxVal: 717 return n 718 } 719 for _, a := range adjust { 720 n = 10*n + seed(a) 721 } 722 return n 723} 724 725// newValue returns a new value assignable to a field. 726// 727// The stack parameter is used to avoid infinite recursion when populating circular 728// data structures. 729func newValue(m protoreflect.Message, fd protoreflect.FieldDescriptor, n seed, stack []protoreflect.MessageDescriptor) protoreflect.Value { 730 switch { 731 case fd.IsList(): 732 if n == 0 { 733 return m.New().Mutable(fd) 734 } 735 list := m.NewField(fd).List() 736 list.Append(newListElement(fd, list, 0, stack)) 737 list.Append(newListElement(fd, list, minVal, stack)) 738 list.Append(newListElement(fd, list, maxVal, stack)) 739 list.Append(newListElement(fd, list, n, stack)) 740 return protoreflect.ValueOfList(list) 741 case fd.IsMap(): 742 if n == 0 { 743 return m.New().Mutable(fd) 744 } 745 mapv := m.NewField(fd).Map() 746 mapv.Set(newMapKey(fd, 0), newMapValue(fd, mapv, 0, stack)) 747 mapv.Set(newMapKey(fd, minVal), newMapValue(fd, mapv, minVal, stack)) 748 mapv.Set(newMapKey(fd, maxVal), newMapValue(fd, mapv, maxVal, stack)) 749 mapv.Set(newMapKey(fd, n), newMapValue(fd, mapv, newSeed(n, 0), stack)) 750 return protoreflect.ValueOfMap(mapv) 751 case fd.Message() != nil: 752 return populateMessage(m.NewField(fd).Message(), n, stack) 753 default: 754 return newScalarValue(fd, n) 755 } 756} 757 758func newListElement(fd protoreflect.FieldDescriptor, list protoreflect.List, n seed, stack []protoreflect.MessageDescriptor) protoreflect.Value { 759 if fd.Message() == nil { 760 return newScalarValue(fd, n) 761 } 762 return populateMessage(list.NewElement().Message(), n, stack) 763} 764 765func newMapKey(fd protoreflect.FieldDescriptor, n seed) protoreflect.MapKey { 766 kd := fd.MapKey() 767 return newScalarValue(kd, n).MapKey() 768} 769 770func newMapValue(fd protoreflect.FieldDescriptor, mapv protoreflect.Map, n seed, stack []protoreflect.MessageDescriptor) protoreflect.Value { 771 vd := fd.MapValue() 772 if vd.Message() == nil { 773 return newScalarValue(vd, n) 774 } 775 return populateMessage(mapv.NewValue().Message(), n, stack) 776} 777 778func newScalarValue(fd protoreflect.FieldDescriptor, n seed) protoreflect.Value { 779 switch fd.Kind() { 780 case protoreflect.BoolKind: 781 return protoreflect.ValueOfBool(n != 0) 782 case protoreflect.EnumKind: 783 vals := fd.Enum().Values() 784 var i int 785 switch n { 786 case minVal: 787 i = 0 788 case maxVal: 789 i = vals.Len() - 1 790 default: 791 i = int(n) % vals.Len() 792 } 793 return protoreflect.ValueOfEnum(vals.Get(i).Number()) 794 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: 795 switch n { 796 case minVal: 797 return protoreflect.ValueOfInt32(math.MinInt32) 798 case maxVal: 799 return protoreflect.ValueOfInt32(math.MaxInt32) 800 default: 801 return protoreflect.ValueOfInt32(int32(n)) 802 } 803 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: 804 switch n { 805 case minVal: 806 // Only use 0 for the zero value. 807 return protoreflect.ValueOfUint32(1) 808 case maxVal: 809 return protoreflect.ValueOfUint32(math.MaxInt32) 810 default: 811 return protoreflect.ValueOfUint32(uint32(n)) 812 } 813 case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: 814 switch n { 815 case minVal: 816 return protoreflect.ValueOfInt64(math.MinInt64) 817 case maxVal: 818 return protoreflect.ValueOfInt64(math.MaxInt64) 819 default: 820 return protoreflect.ValueOfInt64(int64(n)) 821 } 822 case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: 823 switch n { 824 case minVal: 825 // Only use 0 for the zero value. 826 return protoreflect.ValueOfUint64(1) 827 case maxVal: 828 return protoreflect.ValueOfUint64(math.MaxInt64) 829 default: 830 return protoreflect.ValueOfUint64(uint64(n)) 831 } 832 case protoreflect.FloatKind: 833 switch n { 834 case minVal: 835 return protoreflect.ValueOfFloat32(math.SmallestNonzeroFloat32) 836 case maxVal: 837 return protoreflect.ValueOfFloat32(math.MaxFloat32) 838 default: 839 return protoreflect.ValueOfFloat32(1.5 * float32(n)) 840 } 841 case protoreflect.DoubleKind: 842 switch n { 843 case minVal: 844 return protoreflect.ValueOfFloat64(math.SmallestNonzeroFloat64) 845 case maxVal: 846 return protoreflect.ValueOfFloat64(math.MaxFloat64) 847 default: 848 return protoreflect.ValueOfFloat64(1.5 * float64(n)) 849 } 850 case protoreflect.StringKind: 851 if n == 0 { 852 return protoreflect.ValueOfString("") 853 } 854 return protoreflect.ValueOfString(fmt.Sprintf("%d", n)) 855 case protoreflect.BytesKind: 856 if n == 0 { 857 return protoreflect.ValueOfBytes(nil) 858 } 859 return protoreflect.ValueOfBytes([]byte{byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)}) 860 } 861 panic("unhandled kind") 862} 863 864func populateMessage(m protoreflect.Message, n seed, stack []protoreflect.MessageDescriptor) protoreflect.Value { 865 if n == 0 { 866 return protoreflect.ValueOfMessage(m) 867 } 868 md := m.Descriptor() 869 for _, x := range stack { 870 if md == x { 871 return protoreflect.ValueOfMessage(m) 872 } 873 } 874 stack = append(stack, md) 875 for i := 0; i < md.Fields().Len(); i++ { 876 fd := md.Fields().Get(i) 877 if fd.IsWeak() { 878 continue 879 } 880 m.Set(fd, newValue(m, fd, newSeed(n, i), stack)) 881 } 882 return protoreflect.ValueOfMessage(m) 883} 884 885func panics(f func()) (didPanic bool) { 886 defer func() { 887 if err := recover(); err != nil { 888 didPanic = true 889 } 890 }() 891 f() 892 return false 893} 894