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