1package runtime_test
2
3import (
4	"errors"
5	"fmt"
6	"net/url"
7	"reflect"
8	"testing"
9	"time"
10
11	"github.com/golang/protobuf/proto"
12	"github.com/golang/protobuf/ptypes"
13	"github.com/golang/protobuf/ptypes/duration"
14	"github.com/golang/protobuf/ptypes/timestamp"
15	"github.com/golang/protobuf/ptypes/wrappers"
16	"github.com/grpc-ecosystem/grpc-gateway/runtime"
17	"github.com/grpc-ecosystem/grpc-gateway/utilities"
18	"google.golang.org/genproto/protobuf/field_mask"
19)
20
21func BenchmarkPopulateQueryParameters(b *testing.B) {
22	timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
23	timeStr := timeT.Format(time.RFC3339Nano)
24
25	durationT := 13 * time.Hour
26	durationStr := durationT.String()
27
28	fieldmaskStr := "float_value,double_value"
29
30	msg := &proto3Message{}
31	values := url.Values{
32		"float_value":            {"1.5"},
33		"double_value":           {"2.5"},
34		"int64_value":            {"-1"},
35		"int32_value":            {"-2"},
36		"uint64_value":           {"3"},
37		"uint32_value":           {"4"},
38		"bool_value":             {"true"},
39		"string_value":           {"str"},
40		"bytes_value":            {"Ynl0ZXM="},
41		"repeated_value":         {"a", "b", "c"},
42		"enum_value":             {"1"},
43		"repeated_enum":          {"1", "2", "0"},
44		"timestamp_value":        {timeStr},
45		"duration_value":         {durationStr},
46		"fieldmask_value":        {fieldmaskStr},
47		"wrapper_float_value":    {"1.5"},
48		"wrapper_double_value":   {"2.5"},
49		"wrapper_int64_value":    {"-1"},
50		"wrapper_int32_value":    {"-2"},
51		"wrapper_u_int64_value":  {"3"},
52		"wrapper_u_int32_value":  {"4"},
53		"wrapper_bool_value":     {"true"},
54		"wrapper_string_value":   {"str"},
55		"wrapper_bytes_value":    {"Ynl0ZXM="},
56		"map_value[key]":         {"value"},
57		"map_value[second]":      {"bar"},
58		"map_value[third]":       {"zzz"},
59		"map_value[fourth]":      {""},
60		`map_value[~!@#$%^&*()]`: {"value"},
61		"map_value2[key]":        {"-2"},
62		"map_value3[-2]":         {"value"},
63		"map_value4[key]":        {"-1"},
64		"map_value5[-1]":         {"value"},
65		"map_value6[key]":        {"3"},
66		"map_value7[3]":          {"value"},
67		"map_value8[key]":        {"4"},
68		"map_value9[4]":          {"value"},
69		"map_value10[key]":       {"1.5"},
70		"map_value11[1.5]":       {"value"},
71		"map_value12[key]":       {"2.5"},
72		"map_value13[2.5]":       {"value"},
73		"map_value14[key]":       {"true"},
74		"map_value15[true]":      {"value"},
75	}
76	filter := utilities.NewDoubleArray([][]string{
77		{"bool_value"}, {"repeated_value"},
78	})
79
80	for i := 0; i < b.N; i++ {
81		_ = runtime.PopulateQueryParameters(msg, values, filter)
82	}
83}
84
85func TestPopulateParameters(t *testing.T) {
86	timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
87	timeStr := timeT.Format(time.RFC3339Nano)
88	timePb, err := ptypes.TimestampProto(timeT)
89	if err != nil {
90		t.Fatalf("Couldn't setup timestamp in Protobuf format: %v", err)
91	}
92
93	durationT := 13 * time.Hour
94	durationStr := durationT.String()
95	durationPb := ptypes.DurationProto(durationT)
96
97	fieldmaskStr := "float_value,double_value"
98	fieldmaskPb := &field_mask.FieldMask{Paths: []string{"float_value", "double_value"}}
99
100	for _, spec := range []struct {
101		values  url.Values
102		filter  *utilities.DoubleArray
103		want    proto.Message
104		wanterr error
105	}{
106		{
107			values: url.Values{
108				"float_value":            {"1.5"},
109				"double_value":           {"2.5"},
110				"int64_value":            {"-1"},
111				"int32_value":            {"-2"},
112				"uint64_value":           {"3"},
113				"uint32_value":           {"4"},
114				"bool_value":             {"true"},
115				"string_value":           {"str"},
116				"bytes_value":            {"Ynl0ZXM="},
117				"repeated_value":         {"a", "b", "c"},
118				"enum_value":             {"1"},
119				"repeated_enum":          {"1", "2", "0"},
120				"timestamp_value":        {timeStr},
121				"duration_value":         {durationStr},
122				"fieldmask_value":        {fieldmaskStr},
123				"wrapper_float_value":    {"1.5"},
124				"wrapper_double_value":   {"2.5"},
125				"wrapper_int64_value":    {"-1"},
126				"wrapper_int32_value":    {"-2"},
127				"wrapper_u_int64_value":  {"3"},
128				"wrapper_u_int32_value":  {"4"},
129				"wrapper_bool_value":     {"true"},
130				"wrapper_string_value":   {"str"},
131				"wrapper_bytes_value":    {"Ynl0ZXM="},
132				"map_value[key]":         {"value"},
133				"map_value[second]":      {"bar"},
134				"map_value[third]":       {"zzz"},
135				"map_value[fourth]":      {""},
136				`map_value[~!@#$%^&*()]`: {"value"},
137				"map_value2[key]":        {"-2"},
138				"map_value3[-2]":         {"value"},
139				"map_value4[key]":        {"-1"},
140				"map_value5[-1]":         {"value"},
141				"map_value6[key]":        {"3"},
142				"map_value7[3]":          {"value"},
143				"map_value8[key]":        {"4"},
144				"map_value9[4]":          {"value"},
145				"map_value10[key]":       {"1.5"},
146				"map_value11[1.5]":       {"value"},
147				"map_value12[key]":       {"2.5"},
148				"map_value13[2.5]":       {"value"},
149				"map_value14[key]":       {"true"},
150				"map_value15[true]":      {"value"},
151			},
152			filter: utilities.NewDoubleArray(nil),
153			want: &proto3Message{
154				FloatValue:         1.5,
155				DoubleValue:        2.5,
156				Int64Value:         -1,
157				Int32Value:         -2,
158				Uint64Value:        3,
159				Uint32Value:        4,
160				BoolValue:          true,
161				StringValue:        "str",
162				BytesValue:         []byte("bytes"),
163				RepeatedValue:      []string{"a", "b", "c"},
164				EnumValue:          EnumValue_Y,
165				RepeatedEnum:       []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
166				TimestampValue:     timePb,
167				DurationValue:      durationPb,
168				FieldMaskValue:     fieldmaskPb,
169				WrapperFloatValue:  &wrappers.FloatValue{Value: 1.5},
170				WrapperDoubleValue: &wrappers.DoubleValue{Value: 2.5},
171				WrapperInt64Value:  &wrappers.Int64Value{Value: -1},
172				WrapperInt32Value:  &wrappers.Int32Value{Value: -2},
173				WrapperUInt64Value: &wrappers.UInt64Value{Value: 3},
174				WrapperUInt32Value: &wrappers.UInt32Value{Value: 4},
175				WrapperBoolValue:   &wrappers.BoolValue{Value: true},
176				WrapperStringValue: &wrappers.StringValue{Value: "str"},
177				WrapperBytesValue:  &wrappers.BytesValue{Value: []byte("bytes")},
178				MapValue: map[string]string{
179					"key":         "value",
180					"second":      "bar",
181					"third":       "zzz",
182					"fourth":      "",
183					`~!@#$%^&*()`: "value",
184				},
185				MapValue2:  map[string]int32{"key": -2},
186				MapValue3:  map[int32]string{-2: "value"},
187				MapValue4:  map[string]int64{"key": -1},
188				MapValue5:  map[int64]string{-1: "value"},
189				MapValue6:  map[string]uint32{"key": 3},
190				MapValue7:  map[uint32]string{3: "value"},
191				MapValue8:  map[string]uint64{"key": 4},
192				MapValue9:  map[uint64]string{4: "value"},
193				MapValue10: map[string]float32{"key": 1.5},
194				MapValue11: map[float32]string{1.5: "value"},
195				MapValue12: map[string]float64{"key": 2.5},
196				MapValue13: map[float64]string{2.5: "value"},
197				MapValue14: map[string]bool{"key": true},
198				MapValue15: map[bool]string{true: "value"},
199			},
200		},
201		{
202			values: url.Values{
203				"floatValue":         {"1.5"},
204				"doubleValue":        {"2.5"},
205				"int64Value":         {"-1"},
206				"int32Value":         {"-2"},
207				"uint64Value":        {"3"},
208				"uint32Value":        {"4"},
209				"boolValue":          {"true"},
210				"stringValue":        {"str"},
211				"bytesValue":         {"Ynl0ZXM="},
212				"repeatedValue":      {"a", "b", "c"},
213				"enumValue":          {"1"},
214				"repeatedEnum":       {"1", "2", "0"},
215				"timestampValue":     {timeStr},
216				"durationValue":      {durationStr},
217				"fieldmaskValue":     {fieldmaskStr},
218				"wrapperFloatValue":  {"1.5"},
219				"wrapperDoubleValue": {"2.5"},
220				"wrapperInt64Value":  {"-1"},
221				"wrapperInt32Value":  {"-2"},
222				"wrapperUInt64Value": {"3"},
223				"wrapperUInt32Value": {"4"},
224				"wrapperBoolValue":   {"true"},
225				"wrapperStringValue": {"str"},
226				"wrapperBytesValue":  {"Ynl0ZXM="},
227			},
228			filter: utilities.NewDoubleArray(nil),
229			want: &proto3Message{
230				FloatValue:         1.5,
231				DoubleValue:        2.5,
232				Int64Value:         -1,
233				Int32Value:         -2,
234				Uint64Value:        3,
235				Uint32Value:        4,
236				BoolValue:          true,
237				StringValue:        "str",
238				BytesValue:         []byte("bytes"),
239				RepeatedValue:      []string{"a", "b", "c"},
240				EnumValue:          EnumValue_Y,
241				RepeatedEnum:       []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
242				TimestampValue:     timePb,
243				DurationValue:      durationPb,
244				FieldMaskValue:     fieldmaskPb,
245				WrapperFloatValue:  &wrappers.FloatValue{Value: 1.5},
246				WrapperDoubleValue: &wrappers.DoubleValue{Value: 2.5},
247				WrapperInt64Value:  &wrappers.Int64Value{Value: -1},
248				WrapperInt32Value:  &wrappers.Int32Value{Value: -2},
249				WrapperUInt64Value: &wrappers.UInt64Value{Value: 3},
250				WrapperUInt32Value: &wrappers.UInt32Value{Value: 4},
251				WrapperBoolValue:   &wrappers.BoolValue{Value: true},
252				WrapperStringValue: &wrappers.StringValue{Value: "str"},
253				WrapperBytesValue:  &wrappers.BytesValue{Value: []byte("bytes")},
254			},
255		},
256		{
257			values: url.Values{
258				"enum_value":    {"EnumValue_Z"},
259				"repeated_enum": {"EnumValue_X", "2", "0"},
260			},
261			filter: utilities.NewDoubleArray(nil),
262			want: &proto3Message{
263				EnumValue:    EnumValue_Z,
264				RepeatedEnum: []EnumValue{EnumValue_X, EnumValue_Z, EnumValue_X},
265			},
266		},
267		{
268			values: url.Values{
269				"float_value":    {"1.5"},
270				"double_value":   {"2.5"},
271				"int64_value":    {"-1"},
272				"int32_value":    {"-2"},
273				"uint64_value":   {"3"},
274				"uint32_value":   {"4"},
275				"bool_value":     {"true"},
276				"string_value":   {"str"},
277				"repeated_value": {"a", "b", "c"},
278				"enum_value":     {"1"},
279				"repeated_enum":  {"1", "2", "0"},
280			},
281			filter: utilities.NewDoubleArray(nil),
282			want: &proto2Message{
283				FloatValue:    proto.Float32(1.5),
284				DoubleValue:   proto.Float64(2.5),
285				Int64Value:    proto.Int64(-1),
286				Int32Value:    proto.Int32(-2),
287				Uint64Value:   proto.Uint64(3),
288				Uint32Value:   proto.Uint32(4),
289				BoolValue:     proto.Bool(true),
290				StringValue:   proto.String("str"),
291				RepeatedValue: []string{"a", "b", "c"},
292				EnumValue:     EnumValue_Y,
293				RepeatedEnum:  []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
294			},
295		},
296		{
297			values: url.Values{
298				"floatValue":    {"1.5"},
299				"doubleValue":   {"2.5"},
300				"int64Value":    {"-1"},
301				"int32Value":    {"-2"},
302				"uint64Value":   {"3"},
303				"uint32Value":   {"4"},
304				"boolValue":     {"true"},
305				"stringValue":   {"str"},
306				"repeatedValue": {"a", "b", "c"},
307				"enumValue":     {"1"},
308				"repeatedEnum":  {"1", "2", "0"},
309			},
310			filter: utilities.NewDoubleArray(nil),
311			want: &proto2Message{
312				FloatValue:    proto.Float32(1.5),
313				DoubleValue:   proto.Float64(2.5),
314				Int64Value:    proto.Int64(-1),
315				Int32Value:    proto.Int32(-2),
316				Uint64Value:   proto.Uint64(3),
317				Uint32Value:   proto.Uint32(4),
318				BoolValue:     proto.Bool(true),
319				StringValue:   proto.String("str"),
320				RepeatedValue: []string{"a", "b", "c"},
321				EnumValue:     EnumValue_Y,
322				RepeatedEnum:  []EnumValue{EnumValue_Y, EnumValue_Z, EnumValue_X},
323			},
324		},
325		{
326			values: url.Values{
327				"nested.nested.nested.repeated_value": {"a", "b", "c"},
328				"nested.nested.nested.string_value":   {"s"},
329				"nested.nested.string_value":          {"t"},
330				"nested.string_value":                 {"u"},
331				"nested_non_null.string_value":        {"v"},
332				"nested.nested.map_value[first]":      {"foo"},
333				"nested.nested.map_value[second]":     {"bar"},
334			},
335			filter: utilities.NewDoubleArray(nil),
336			want: &proto3Message{
337				Nested: &proto2Message{
338					Nested: &proto3Message{
339						MapValue: map[string]string{
340							"first":  "foo",
341							"second": "bar",
342						},
343						Nested: &proto2Message{
344							RepeatedValue: []string{"a", "b", "c"},
345							StringValue:   proto.String("s"),
346						},
347						StringValue: "t",
348					},
349					StringValue: proto.String("u"),
350				},
351				NestedNonNull: proto2Message{
352					StringValue: proto.String("v"),
353				},
354			},
355		},
356		{
357			values: url.Values{
358				"uint64_value": {"1", "2", "3", "4", "5"},
359			},
360			filter: utilities.NewDoubleArray(nil),
361			want: &proto3Message{
362				Uint64Value: 1,
363			},
364		},
365		{
366			values: url.Values{
367				"oneof_string_value": {"foobar"},
368			},
369			filter: utilities.NewDoubleArray(nil),
370			want: &proto3Message{
371				OneofValue: &proto3Message_OneofStringValue{"foobar"},
372			},
373		},
374		{
375			values: url.Values{
376				"oneofStringValue": {"foobar"},
377			},
378			filter: utilities.NewDoubleArray(nil),
379			want: &proto3Message{
380				OneofValue: &proto3Message_OneofStringValue{"foobar"},
381			},
382		},
383		{
384			values: url.Values{
385				"oneof_bool_value": {"true"},
386			},
387			filter: utilities.NewDoubleArray(nil),
388			want: &proto3Message{
389				OneofValue: &proto3Message_OneofBoolValue{true},
390			},
391		},
392		{
393			// Don't allow setting a oneof more than once
394			values: url.Values{
395				"oneof_bool_value":   {"true"},
396				"oneof_string_value": {"foobar"},
397			},
398			filter:  utilities.NewDoubleArray(nil),
399			want:    &proto3Message{},
400			wanterr: errors.New("field already set for oneof_value oneof"),
401		},
402	} {
403		msg := proto.Clone(spec.want)
404		msg.Reset()
405		err := runtime.PopulateQueryParameters(msg, spec.values, spec.filter)
406		if spec.wanterr != nil {
407			if !reflect.DeepEqual(err, spec.wanterr) {
408				t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) failed with %v; want error %v", spec.values, spec.filter, err, spec.wanterr)
409			}
410			continue
411		}
412
413		if err != nil {
414			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) failed with %v; want success", spec.values, spec.filter, err)
415			continue
416		}
417		if got, want := msg, spec.want; !proto.Equal(got, want) {
418			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v = %v; want %v", spec.values, spec.filter, got, want)
419		}
420	}
421}
422
423func TestPopulateParametersWithNativeTypes(t *testing.T) {
424	timeT := time.Date(2016, time.December, 15, 12, 23, 32, 49, time.UTC)
425	timeStr := timeT.Format(time.RFC3339Nano)
426
427	durationT := 13 * time.Hour
428	durationStr := durationT.String()
429
430	for _, spec := range []struct {
431		values url.Values
432		want   *nativeProto3Message
433	}{
434		{
435			values: url.Values{
436				"native_timestamp_value": {timeStr},
437				"native_duration_value":  {durationStr},
438			},
439			want: &nativeProto3Message{
440				NativeTimeValue:     &timeT,
441				NativeDurationValue: &durationT,
442			},
443		},
444		{
445			values: url.Values{
446				"nativeTimestampValue": {timeStr},
447				"nativeDurationValue":  {durationStr},
448			},
449			want: &nativeProto3Message{
450				NativeTimeValue:     &timeT,
451				NativeDurationValue: &durationT,
452			},
453		},
454	} {
455		msg := new(nativeProto3Message)
456		err := runtime.PopulateQueryParameters(msg, spec.values, utilities.NewDoubleArray(nil))
457
458		if err != nil {
459			t.Errorf("runtime.PopulateQueryParameters(msg, %v, utilities.NewDoubleArray(nil)) failed with %v; want success", spec.values, err)
460			continue
461		}
462		if got, want := msg, spec.want; !proto.Equal(got, want) {
463			t.Errorf("runtime.PopulateQueryParameters(msg, %v, utilities.NewDoubleArray(nil)) = %v; want %v", spec.values, got, want)
464		}
465	}
466}
467
468func TestPopulateParametersWithFilters(t *testing.T) {
469	for _, spec := range []struct {
470		values url.Values
471		filter *utilities.DoubleArray
472		want   proto.Message
473	}{
474		{
475			values: url.Values{
476				"bool_value":     {"true"},
477				"string_value":   {"str"},
478				"repeated_value": {"a", "b", "c"},
479			},
480			filter: utilities.NewDoubleArray([][]string{
481				{"bool_value"}, {"repeated_value"},
482			}),
483			want: &proto3Message{
484				StringValue: "str",
485			},
486		},
487		{
488			values: url.Values{
489				"nested.nested.bool_value":   {"true"},
490				"nested.nested.string_value": {"str"},
491				"nested.string_value":        {"str"},
492				"string_value":               {"str"},
493			},
494			filter: utilities.NewDoubleArray([][]string{
495				{"nested"},
496			}),
497			want: &proto3Message{
498				StringValue: "str",
499			},
500		},
501		{
502			values: url.Values{
503				"nested.nested.bool_value":   {"true"},
504				"nested.nested.string_value": {"str"},
505				"nested.string_value":        {"str"},
506				"string_value":               {"str"},
507			},
508			filter: utilities.NewDoubleArray([][]string{
509				{"nested", "nested"},
510			}),
511			want: &proto3Message{
512				Nested: &proto2Message{
513					StringValue: proto.String("str"),
514				},
515				StringValue: "str",
516			},
517		},
518		{
519			values: url.Values{
520				"nested.nested.bool_value":   {"true"},
521				"nested.nested.string_value": {"str"},
522				"nested.string_value":        {"str"},
523				"string_value":               {"str"},
524			},
525			filter: utilities.NewDoubleArray([][]string{
526				{"nested", "nested", "string_value"},
527			}),
528			want: &proto3Message{
529				Nested: &proto2Message{
530					StringValue: proto.String("str"),
531					Nested: &proto3Message{
532						BoolValue: true,
533					},
534				},
535				StringValue: "str",
536			},
537		},
538	} {
539		msg := proto.Clone(spec.want)
540		msg.Reset()
541		err := runtime.PopulateQueryParameters(msg, spec.values, spec.filter)
542		if err != nil {
543			t.Errorf("runtime.PoplateQueryParameters(msg, %v, %v) failed with %v; want success", spec.values, spec.filter, err)
544			continue
545		}
546		if got, want := msg, spec.want; !proto.Equal(got, want) {
547			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v = %v; want %v", spec.values, spec.filter, got, want)
548		}
549	}
550}
551
552func TestPopulateQueryParametersWithInvalidNestedParameters(t *testing.T) {
553	for _, spec := range []struct {
554		msg    proto.Message
555		values url.Values
556		filter *utilities.DoubleArray
557	}{
558		{
559			msg: &proto3Message{},
560			values: url.Values{
561				"float_value.nested": {"test"},
562			},
563			filter: utilities.NewDoubleArray(nil),
564		},
565		{
566			msg: &proto3Message{},
567			values: url.Values{
568				"double_value.nested": {"test"},
569			},
570			filter: utilities.NewDoubleArray(nil),
571		},
572		{
573			msg: &proto3Message{},
574			values: url.Values{
575				"int64_value.nested": {"test"},
576			},
577			filter: utilities.NewDoubleArray(nil),
578		},
579		{
580			msg: &proto3Message{},
581			values: url.Values{
582				"int32_value.nested": {"test"},
583			},
584			filter: utilities.NewDoubleArray(nil),
585		},
586		{
587			msg: &proto3Message{},
588			values: url.Values{
589				"uint64_value.nested": {"test"},
590			},
591			filter: utilities.NewDoubleArray(nil),
592		},
593		{
594			msg: &proto3Message{},
595			values: url.Values{
596				"uint32_value.nested": {"test"},
597			},
598			filter: utilities.NewDoubleArray(nil),
599		},
600		{
601			msg: &proto3Message{},
602			values: url.Values{
603				"bool_value.nested": {"test"},
604			},
605			filter: utilities.NewDoubleArray(nil),
606		},
607		{
608			msg: &proto3Message{},
609			values: url.Values{
610				"string_value.nested": {"test"},
611			},
612			filter: utilities.NewDoubleArray(nil),
613		},
614		{
615			msg: &proto3Message{},
616			values: url.Values{
617				"repeated_value.nested": {"test"},
618			},
619			filter: utilities.NewDoubleArray(nil),
620		},
621		{
622			msg: &proto3Message{},
623			values: url.Values{
624				"enum_value.nested": {"test"},
625			},
626			filter: utilities.NewDoubleArray(nil),
627		},
628		{
629			msg: &proto3Message{},
630			values: url.Values{
631				"enum_value.nested": {"test"},
632			},
633			filter: utilities.NewDoubleArray(nil),
634		},
635		{
636			msg: &proto3Message{},
637			values: url.Values{
638				"repeated_enum.nested": {"test"},
639			},
640			filter: utilities.NewDoubleArray(nil),
641		},
642	} {
643		spec.msg.Reset()
644		err := runtime.PopulateQueryParameters(spec.msg, spec.values, spec.filter)
645		if err == nil {
646			t.Errorf("runtime.PopulateQueryParameters(msg, %v, %v) did not fail; want error", spec.values, spec.filter)
647		}
648	}
649}
650
651type proto3Message struct {
652	Nested             *proto2Message           `protobuf:"bytes,1,opt,name=nested,json=nested" json:"nested,omitempty"`
653	NestedNonNull      proto2Message            `protobuf:"bytes,15,opt,name=nested_non_null,json=nestedNonNull" json:"nested_non_null,omitempty"`
654	FloatValue         float32                  `protobuf:"fixed32,2,opt,name=float_value,json=floatValue" json:"float_value,omitempty"`
655	DoubleValue        float64                  `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"`
656	Int64Value         int64                    `protobuf:"varint,4,opt,name=int64_value,json=int64Value" json:"int64_value,omitempty"`
657	Int32Value         int32                    `protobuf:"varint,5,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"`
658	Uint64Value        uint64                   `protobuf:"varint,6,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"`
659	Uint32Value        uint32                   `protobuf:"varint,7,opt,name=uint32_value,json=uint32Value" json:"uint32_value,omitempty"`
660	BoolValue          bool                     `protobuf:"varint,8,opt,name=bool_value,json=boolValue" json:"bool_value,omitempty"`
661	StringValue        string                   `protobuf:"bytes,9,opt,name=string_value,json=stringValue" json:"string_value,omitempty"`
662	BytesValue         []byte                   `protobuf:"bytes,25,opt,name=bytes_value,json=bytesValue" json:"bytes_value,omitempty"`
663	RepeatedValue      []string                 `protobuf:"bytes,10,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
664	EnumValue          EnumValue                `protobuf:"varint,11,opt,name=enum_value,json=enumValue,enum=runtime_test_api.EnumValue" json:"enum_value,omitempty"`
665	RepeatedEnum       []EnumValue              `protobuf:"varint,12,rep,packed,name=repeated_enum,json=repeatedEnum,enum=runtime_test_api.EnumValue" json:"repeated_enum,omitempty"`
666	TimestampValue     *timestamp.Timestamp     `protobuf:"bytes,16,opt,name=timestamp_value,json=timestampValue" json:"timestamp_value,omitempty"`
667	DurationValue      *duration.Duration       `protobuf:"bytes,42,opt,name=duration_value,json=durationValue" json:"duration_value,omitempty"`
668	FieldMaskValue     *field_mask.FieldMask    `protobuf:"bytes,27,opt,name=fieldmask_value,json=fieldmaskValue" json:"fieldmask_value,omitempty"`
669	OneofValue         proto3Message_OneofValue `protobuf_oneof:"oneof_value"`
670	WrapperDoubleValue *wrappers.DoubleValue    `protobuf:"bytes,17,opt,name=wrapper_double_value,json=wrapperDoubleValue" json:"wrapper_double_value,omitempty"`
671	WrapperFloatValue  *wrappers.FloatValue     `protobuf:"bytes,18,opt,name=wrapper_float_value,json=wrapperFloatValue" json:"wrapper_float_value,omitempty"`
672	WrapperInt64Value  *wrappers.Int64Value     `protobuf:"bytes,19,opt,name=wrapper_int64_value,json=wrapperInt64Value" json:"wrapper_int64_value,omitempty"`
673	WrapperInt32Value  *wrappers.Int32Value     `protobuf:"bytes,20,opt,name=wrapper_int32_value,json=wrapperInt32Value" json:"wrapper_int32_value,omitempty"`
674	WrapperUInt64Value *wrappers.UInt64Value    `protobuf:"bytes,21,opt,name=wrapper_u_int64_value,json=wrapperUInt64Value" json:"wrapper_u_int64_value,omitempty"`
675	WrapperUInt32Value *wrappers.UInt32Value    `protobuf:"bytes,22,opt,name=wrapper_u_int32_value,json=wrapperUInt32Value" json:"wrapper_u_int32_value,omitempty"`
676	WrapperBoolValue   *wrappers.BoolValue      `protobuf:"bytes,23,opt,name=wrapper_bool_value,json=wrapperBoolValue" json:"wrapper_bool_value,omitempty"`
677	WrapperStringValue *wrappers.StringValue    `protobuf:"bytes,24,opt,name=wrapper_string_value,json=wrapperStringValue" json:"wrapper_string_value,omitempty"`
678	WrapperBytesValue  *wrappers.BytesValue     `protobuf:"bytes,26,opt,name=wrapper_bytes_value,json=wrapperBytesValue" json:"wrapper_bytes_value,omitempty"`
679	MapValue           map[string]string        `protobuf:"bytes,27,opt,name=map_value,json=mapValue" json:"map_value,omitempty"`
680	MapValue2          map[string]int32         `protobuf:"bytes,28,opt,name=map_value2,json=mapValue2" json:"map_value2,omitempty"`
681	MapValue3          map[int32]string         `protobuf:"bytes,29,opt,name=map_value3,json=mapValue3" json:"map_value3,omitempty"`
682	MapValue4          map[string]int64         `protobuf:"bytes,30,opt,name=map_value4,json=mapValue4" json:"map_value4,omitempty"`
683	MapValue5          map[int64]string         `protobuf:"bytes,31,opt,name=map_value5,json=mapValue5" json:"map_value5,omitempty"`
684	MapValue6          map[string]uint32        `protobuf:"bytes,32,opt,name=map_value6,json=mapValue6" json:"map_value6,omitempty"`
685	MapValue7          map[uint32]string        `protobuf:"bytes,33,opt,name=map_value7,json=mapValue7" json:"map_value7,omitempty"`
686	MapValue8          map[string]uint64        `protobuf:"bytes,34,opt,name=map_value8,json=mapValue8" json:"map_value8,omitempty"`
687	MapValue9          map[uint64]string        `protobuf:"bytes,35,opt,name=map_value9,json=mapValue9" json:"map_value9,omitempty"`
688	MapValue10         map[string]float32       `protobuf:"bytes,36,opt,name=map_value10,json=mapValue10" json:"map_value10,omitempty"`
689	MapValue11         map[float32]string       `protobuf:"bytes,37,opt,name=map_value11,json=mapValue11" json:"map_value11,omitempty"`
690	MapValue12         map[string]float64       `protobuf:"bytes,38,opt,name=map_value12,json=mapValue12" json:"map_value12,omitempty"`
691	MapValue13         map[float64]string       `protobuf:"bytes,39,opt,name=map_value13,json=mapValue13" json:"map_value13,omitempty"`
692	MapValue14         map[string]bool          `protobuf:"bytes,40,opt,name=map_value14,json=mapValue14" json:"map_value14,omitempty"`
693	MapValue15         map[bool]string          `protobuf:"bytes,41,opt,name=map_value15,json=mapValue15" json:"map_value15,omitempty"`
694}
695
696func (m *proto3Message) Reset()         { *m = proto3Message{} }
697func (m *proto3Message) String() string { return proto.CompactTextString(m) }
698func (*proto3Message) ProtoMessage()    {}
699
700func (m *proto3Message) GetNested() *proto2Message {
701	if m != nil {
702		return m.Nested
703	}
704	return nil
705}
706
707type proto3Message_OneofValue interface {
708	proto3Message_OneofValue()
709}
710
711type proto3Message_OneofBoolValue struct {
712	OneofBoolValue bool `protobuf:"varint,13,opt,name=oneof_bool_value,json=oneofBoolValue,oneof"`
713}
714type proto3Message_OneofStringValue struct {
715	OneofStringValue string `protobuf:"bytes,14,opt,name=oneof_string_value,json=oneofStringValue,oneof"`
716}
717
718func (*proto3Message_OneofBoolValue) proto3Message_OneofValue()   {}
719func (*proto3Message_OneofStringValue) proto3Message_OneofValue() {}
720
721func (m *proto3Message) GetOneofValue() proto3Message_OneofValue {
722	if m != nil {
723		return m.OneofValue
724	}
725	return nil
726}
727
728func (m *proto3Message) GetOneofBoolValue() bool {
729	if x, ok := m.GetOneofValue().(*proto3Message_OneofBoolValue); ok {
730		return x.OneofBoolValue
731	}
732	return false
733}
734
735func (m *proto3Message) GetOneofStringValue() string {
736	if x, ok := m.GetOneofValue().(*proto3Message_OneofStringValue); ok {
737		return x.OneofStringValue
738	}
739	return ""
740}
741
742// XXX_OneofFuncs is for the internal use of the proto package.
743func (*proto3Message) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
744	return _proto3Message_OneofMarshaler, _proto3Message_OneofUnmarshaler, _proto3Message_OneofSizer, []interface{}{
745		(*proto3Message_OneofBoolValue)(nil),
746		(*proto3Message_OneofStringValue)(nil),
747	}
748}
749
750func _proto3Message_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
751	m := msg.(*proto3Message)
752	// oneof_value
753	switch x := m.OneofValue.(type) {
754	case *proto3Message_OneofBoolValue:
755		t := uint64(0)
756		if x.OneofBoolValue {
757			t = 1
758		}
759		b.EncodeVarint(13<<3 | proto.WireVarint)
760		b.EncodeVarint(t)
761	case *proto3Message_OneofStringValue:
762		b.EncodeVarint(14<<3 | proto.WireBytes)
763		b.EncodeStringBytes(x.OneofStringValue)
764	case nil:
765	default:
766		return fmt.Errorf("proto3Message.OneofValue has unexpected type %T", x)
767	}
768	return nil
769}
770
771func _proto3Message_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
772	m := msg.(*proto3Message)
773	switch tag {
774	case 14: // oneof_value.oneof_bool_value
775		if wire != proto.WireVarint {
776			return true, proto.ErrInternalBadWireType
777		}
778		x, err := b.DecodeVarint()
779		m.OneofValue = &proto3Message_OneofBoolValue{x != 0}
780		return true, err
781	case 15: // oneof_value.oneof_string_value
782		if wire != proto.WireBytes {
783			return true, proto.ErrInternalBadWireType
784		}
785		x, err := b.DecodeStringBytes()
786		m.OneofValue = &proto3Message_OneofStringValue{x}
787		return true, err
788	default:
789		return false, nil
790	}
791}
792
793func _proto3Message_OneofSizer(msg proto.Message) (n int) {
794	m := msg.(*proto3Message)
795	// oneof_value
796	switch x := m.OneofValue.(type) {
797	case *proto3Message_OneofBoolValue:
798		n += proto.SizeVarint(14<<3 | proto.WireVarint)
799		n += 1
800	case *proto3Message_OneofStringValue:
801		n += proto.SizeVarint(15<<3 | proto.WireBytes)
802		n += proto.SizeVarint(uint64(len(x.OneofStringValue)))
803		n += len(x.OneofStringValue)
804	case nil:
805	default:
806		panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
807	}
808	return n
809}
810
811type nativeProto3Message struct {
812	NativeTimeValue     *time.Time     `protobuf:"bytes,1,opt,name=native_timestamp_value,json=nativeTimestampValue" json:"native_timestamp_value,omitempty"`
813	NativeDurationValue *time.Duration `protobuf:"bytes,2,opt,name=native_duration_value,json=nativeDurationValue" json:"native_duration_value,omitempty"`
814}
815
816func (m *nativeProto3Message) Reset()         { *m = nativeProto3Message{} }
817func (m *nativeProto3Message) String() string { return proto.CompactTextString(m) }
818func (*nativeProto3Message) ProtoMessage()    {}
819
820type proto2Message struct {
821	Nested           *proto3Message `protobuf:"bytes,1,opt,name=nested,json=nested" json:"nested,omitempty"`
822	FloatValue       *float32       `protobuf:"fixed32,2,opt,name=float_value,json=floatValue" json:"float_value,omitempty"`
823	DoubleValue      *float64       `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"`
824	Int64Value       *int64         `protobuf:"varint,4,opt,name=int64_value,json=int64Value" json:"int64_value,omitempty"`
825	Int32Value       *int32         `protobuf:"varint,5,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"`
826	Uint64Value      *uint64        `protobuf:"varint,6,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"`
827	Uint32Value      *uint32        `protobuf:"varint,7,opt,name=uint32_value,json=uint32Value" json:"uint32_value,omitempty"`
828	BoolValue        *bool          `protobuf:"varint,8,opt,name=bool_value,json=boolValue" json:"bool_value,omitempty"`
829	StringValue      *string        `protobuf:"bytes,9,opt,name=string_value,json=stringValue" json:"string_value,omitempty"`
830	RepeatedValue    []string       `protobuf:"bytes,10,rep,name=repeated_value,json=repeatedValue" json:"repeated_value,omitempty"`
831	EnumValue        EnumValue      `protobuf:"varint,11,opt,name=enum_value,json=enumValue,enum=runtime_test_api.EnumValue" json:"enum_value,omitempty"`
832	RepeatedEnum     []EnumValue    `protobuf:"varint,12,rep,packed,name=repeated_enum,json=repeatedEnum,enum=runtime_test_api.EnumValue" json:"repeated_enum,omitempty"`
833	XXX_unrecognized []byte         `json:"-"`
834}
835
836func (m *proto2Message) Reset()         { *m = proto2Message{} }
837func (m *proto2Message) String() string { return proto.CompactTextString(m) }
838func (*proto2Message) ProtoMessage()    {}
839
840func (m *proto2Message) GetNested() *proto3Message {
841	if m != nil {
842		return m.Nested
843	}
844	return nil
845}
846
847func (m *proto2Message) GetFloatValue() float32 {
848	if m != nil && m.FloatValue != nil {
849		return *m.FloatValue
850	}
851	return 0
852}
853
854func (m *proto2Message) GetDoubleValue() float64 {
855	if m != nil && m.DoubleValue != nil {
856		return *m.DoubleValue
857	}
858	return 0
859}
860
861func (m *proto2Message) GetInt64Value() int64 {
862	if m != nil && m.Int64Value != nil {
863		return *m.Int64Value
864	}
865	return 0
866}
867
868func (m *proto2Message) GetInt32Value() int32 {
869	if m != nil && m.Int32Value != nil {
870		return *m.Int32Value
871	}
872	return 0
873}
874
875func (m *proto2Message) GetUint64Value() uint64 {
876	if m != nil && m.Uint64Value != nil {
877		return *m.Uint64Value
878	}
879	return 0
880}
881
882func (m *proto2Message) GetUint32Value() uint32 {
883	if m != nil && m.Uint32Value != nil {
884		return *m.Uint32Value
885	}
886	return 0
887}
888
889func (m *proto2Message) GetBoolValue() bool {
890	if m != nil && m.BoolValue != nil {
891		return *m.BoolValue
892	}
893	return false
894}
895
896func (m *proto2Message) GetStringValue() string {
897	if m != nil && m.StringValue != nil {
898		return *m.StringValue
899	}
900	return ""
901}
902
903func (m *proto2Message) GetRepeatedValue() []string {
904	if m != nil {
905		return m.RepeatedValue
906	}
907	return nil
908}
909
910type EnumValue int32
911
912const (
913	EnumValue_X EnumValue = 0
914	EnumValue_Y EnumValue = 1
915	EnumValue_Z EnumValue = 2
916)
917
918var EnumValue_name = map[int32]string{
919	0: "EnumValue_X",
920	1: "EnumValue_Y",
921	2: "EnumValue_Z",
922}
923var EnumValue_value = map[string]int32{
924	"EnumValue_X": 0,
925	"EnumValue_Y": 1,
926	"EnumValue_Z": 2,
927}
928
929func init() {
930	proto.RegisterEnum("runtime_test_api.EnumValue", EnumValue_name, EnumValue_value)
931}
932