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