1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adapt
16
17 import (
18 "encoding/json"
19 "reflect"
20 "testing"
21
22 "cloud.google.com/go/bigquery/storage/apiv1/storagepb"
23 "cloud.google.com/go/bigquery/storage/managedwriter/testdata"
24 "github.com/google/go-cmp/cmp"
25 "google.golang.org/protobuf/encoding/protojson"
26 "google.golang.org/protobuf/proto"
27 "google.golang.org/protobuf/reflect/protodesc"
28 "google.golang.org/protobuf/reflect/protoreflect"
29 "google.golang.org/protobuf/testing/protocmp"
30 "google.golang.org/protobuf/types/descriptorpb"
31 "google.golang.org/protobuf/types/dynamicpb"
32 )
33
34
35
36
37
38
39
40
41
42
43 func TestSchemaToProtoConversion(t *testing.T) {
44 testCases := []struct {
45 description string
46 bq *storagepb.TableSchema
47
48 wantProto2 *descriptorpb.DescriptorProto
49
50 wantProto2Normalized *descriptorpb.DescriptorProto
51
52
53 wantProto3 *descriptorpb.DescriptorProto
54
55 wantProto3Normalized *descriptorpb.DescriptorProto
56 }{
57 {
58 description: "basic",
59 bq: &storagepb.TableSchema{
60 Fields: []*storagepb.TableFieldSchema{
61 {Name: "foo", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_NULLABLE},
62 {Name: "bar", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_REQUIRED},
63 {Name: "baz", Type: storagepb.TableFieldSchema_BYTES, Mode: storagepb.TableFieldSchema_REPEATED},
64 }},
65 wantProto2: &descriptorpb.DescriptorProto{
66 Name: proto.String("root"),
67 Field: []*descriptorpb.FieldDescriptorProto{
68 {
69 Name: proto.String("foo"),
70 Number: proto.Int32(1),
71 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
72 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
73 {Name: proto.String("bar"), Number: proto.Int32(2), Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(), Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum()},
74 {Name: proto.String("baz"), Number: proto.Int32(3), Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(), Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum()},
75 },
76 },
77 wantProto2Normalized: &descriptorpb.DescriptorProto{
78 Name: proto.String("root"),
79 Field: []*descriptorpb.FieldDescriptorProto{
80 {
81 Name: proto.String("foo"),
82 Number: proto.Int32(1),
83 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
84 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
85 {Name: proto.String("bar"), Number: proto.Int32(2), Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(), Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum()},
86 {Name: proto.String("baz"), Number: proto.Int32(3), Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(), Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum()},
87 },
88 },
89 wantProto3: &descriptorpb.DescriptorProto{
90 Name: proto.String("root"),
91 Field: []*descriptorpb.FieldDescriptorProto{
92 {
93 Name: proto.String("foo"),
94 Number: proto.Int32(1),
95 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
96 TypeName: proto.String(".google.protobuf.StringValue"),
97 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
98 {Name: proto.String("bar"), Number: proto.Int32(2), Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(), Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
99 {Name: proto.String("baz"), Number: proto.Int32(3), Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(), Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum()},
100 },
101 },
102 },
103 {
104
105 description: "nested",
106 bq: &storagepb.TableSchema{
107 Fields: []*storagepb.TableFieldSchema{
108 {Name: "curdate", Type: storagepb.TableFieldSchema_DATE, Mode: storagepb.TableFieldSchema_NULLABLE},
109 {
110 Name: "rec",
111 Type: storagepb.TableFieldSchema_STRUCT,
112 Mode: storagepb.TableFieldSchema_NULLABLE,
113 Fields: []*storagepb.TableFieldSchema{
114 {Name: "userid", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_REQUIRED},
115 {Name: "location", Type: storagepb.TableFieldSchema_GEOGRAPHY, Mode: storagepb.TableFieldSchema_NULLABLE},
116 },
117 },
118 },
119 },
120 wantProto2: &descriptorpb.DescriptorProto{
121 Name: proto.String("root"),
122 Field: []*descriptorpb.FieldDescriptorProto{
123 {
124 Name: proto.String("curdate"),
125 Number: proto.Int32(1),
126 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
127 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
128 },
129 {
130 Name: proto.String("rec"),
131 Number: proto.Int32(2),
132 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
133 TypeName: proto.String(".root__rec"),
134 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
135 },
136 },
137 },
138 wantProto2Normalized: &descriptorpb.DescriptorProto{
139 Name: proto.String("root"),
140 Field: []*descriptorpb.FieldDescriptorProto{
141 {
142 Name: proto.String("curdate"),
143 Number: proto.Int32(1),
144 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
145 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
146 },
147 {
148 Name: proto.String("rec"),
149 Number: proto.Int32(2),
150 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
151 TypeName: proto.String("root__rec"),
152 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
153 },
154 },
155 NestedType: []*descriptorpb.DescriptorProto{
156 {
157 Name: proto.String("root__rec"),
158 Field: []*descriptorpb.FieldDescriptorProto{
159 {
160 Name: proto.String("userid"),
161 Number: proto.Int32(1),
162 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
163 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
164 },
165 {
166 Name: proto.String("location"),
167 Number: proto.Int32(2),
168 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
169 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
170 },
171 },
172 },
173 },
174 },
175 wantProto3: &descriptorpb.DescriptorProto{
176 Name: proto.String("root"),
177 Field: []*descriptorpb.FieldDescriptorProto{
178 {
179 Name: proto.String("curdate"),
180 Number: proto.Int32(1),
181 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
182 TypeName: proto.String(".google.protobuf.Int32Value"),
183 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
184 },
185 {
186 Name: proto.String("rec"),
187 Number: proto.Int32(2),
188 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
189 TypeName: proto.String(".root__rec"),
190 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
191 },
192 },
193 },
194 },
195 {
196
197 description: "range types",
198 bq: &storagepb.TableSchema{
199 Fields: []*storagepb.TableFieldSchema{
200 {
201 Name: "rangedate",
202 Type: storagepb.TableFieldSchema_RANGE,
203 Mode: storagepb.TableFieldSchema_NULLABLE,
204 RangeElementType: &storagepb.TableFieldSchema_FieldElementType{Type: storagepb.TableFieldSchema_DATE},
205 },
206 {
207 Name: "rangedatetime",
208 Type: storagepb.TableFieldSchema_RANGE,
209 Mode: storagepb.TableFieldSchema_NULLABLE,
210 RangeElementType: &storagepb.TableFieldSchema_FieldElementType{Type: storagepb.TableFieldSchema_DATETIME},
211 },
212 {
213 Name: "rangetimestamp",
214 Type: storagepb.TableFieldSchema_RANGE,
215 Mode: storagepb.TableFieldSchema_NULLABLE,
216 RangeElementType: &storagepb.TableFieldSchema_FieldElementType{Type: storagepb.TableFieldSchema_TIMESTAMP},
217 },
218 {
219 Name: "duplicate_rangedate",
220 Type: storagepb.TableFieldSchema_RANGE,
221 Mode: storagepb.TableFieldSchema_NULLABLE,
222 RangeElementType: &storagepb.TableFieldSchema_FieldElementType{Type: storagepb.TableFieldSchema_DATE},
223 },
224 },
225 },
226 wantProto2: &descriptorpb.DescriptorProto{
227 Name: proto.String("root"),
228 Field: []*descriptorpb.FieldDescriptorProto{
229 {
230 Name: proto.String("rangedate"),
231 Number: proto.Int32(1),
232 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
233 TypeName: proto.String(".rangemessage_range_date"),
234 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
235 },
236 {
237 Name: proto.String("rangedatetime"),
238 Number: proto.Int32(2),
239 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
240 TypeName: proto.String(".rangemessage_range_datetime"),
241 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
242 },
243 {
244 Name: proto.String("rangetimestamp"),
245 Number: proto.Int32(3),
246 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
247 TypeName: proto.String(".rangemessage_range_timestamp"),
248 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
249 },
250 {
251 Name: proto.String("duplicate_rangedate"),
252 Number: proto.Int32(4),
253 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
254 TypeName: proto.String(".rangemessage_range_date"),
255 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
256 },
257 },
258 },
259 wantProto2Normalized: &descriptorpb.DescriptorProto{
260 Name: proto.String("root"),
261 Field: []*descriptorpb.FieldDescriptorProto{
262 {
263 Name: proto.String("rangedate"),
264 Number: proto.Int32(1),
265 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
266 TypeName: proto.String("rangemessage_range_date"),
267 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
268 },
269 {
270 Name: proto.String("rangedatetime"),
271 Number: proto.Int32(2),
272 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
273 TypeName: proto.String("rangemessage_range_datetime"),
274 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
275 },
276 {
277 Name: proto.String("rangetimestamp"),
278 Number: proto.Int32(3),
279 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
280 TypeName: proto.String("rangemessage_range_timestamp"),
281 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
282 },
283 {
284 Name: proto.String("duplicate_rangedate"),
285 Number: proto.Int32(4),
286 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
287 TypeName: proto.String("rangemessage_range_date"),
288 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
289 },
290 },
291 NestedType: []*descriptorpb.DescriptorProto{
292 {
293 Name: proto.String("rangemessage_range_date"),
294 Field: []*descriptorpb.FieldDescriptorProto{
295 {
296 Name: proto.String("start"),
297 Number: proto.Int32(1),
298 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
299 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
300 },
301 {
302 Name: proto.String("end"),
303 Number: proto.Int32(2),
304 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
305 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
306 },
307 },
308 },
309 {
310 Name: proto.String("rangemessage_range_datetime"),
311 Field: []*descriptorpb.FieldDescriptorProto{
312 {
313 Name: proto.String("start"),
314 Number: proto.Int32(1),
315 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
316 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
317 },
318 {
319 Name: proto.String("end"),
320 Number: proto.Int32(2),
321 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
322 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
323 },
324 },
325 },
326 {
327 Name: proto.String("rangemessage_range_timestamp"),
328 Field: []*descriptorpb.FieldDescriptorProto{
329 {
330 Name: proto.String("start"),
331 Number: proto.Int32(1),
332 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
333 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
334 },
335 {
336 Name: proto.String("end"),
337 Number: proto.Int32(2),
338 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
339 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
340 },
341 },
342 },
343 },
344 },
345 wantProto3: &descriptorpb.DescriptorProto{
346 Name: proto.String("root"),
347 Field: []*descriptorpb.FieldDescriptorProto{
348 {
349 Name: proto.String("rangedate"),
350 Number: proto.Int32(1),
351 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
352 TypeName: proto.String(".rangemessage_range_date"),
353 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
354 },
355 {
356 Name: proto.String("rangedatetime"),
357 Number: proto.Int32(2),
358 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
359 TypeName: proto.String(".rangemessage_range_datetime"),
360 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
361 },
362 {
363 Name: proto.String("rangetimestamp"),
364 Number: proto.Int32(3),
365 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
366 TypeName: proto.String(".rangemessage_range_timestamp"),
367 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
368 },
369 {
370 Name: proto.String("duplicate_rangedate"),
371 Number: proto.Int32(4),
372 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
373 TypeName: proto.String(".rangemessage_range_date"),
374 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
375 },
376 },
377 },
378 },
379 {
380 description: "nested-uppercase",
381 bq: &storagepb.TableSchema{
382 Fields: []*storagepb.TableFieldSchema{
383 {Name: "recordID", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_REQUIRED},
384 {
385 Name: "recordDetails",
386 Type: storagepb.TableFieldSchema_STRUCT,
387 Mode: storagepb.TableFieldSchema_REPEATED,
388 Fields: []*storagepb.TableFieldSchema{
389 {Name: "key", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_REQUIRED},
390 {Name: "value", Type: storagepb.TableFieldSchema_BYTES, Mode: storagepb.TableFieldSchema_NULLABLE},
391 },
392 },
393 },
394 },
395 wantProto2: &descriptorpb.DescriptorProto{
396 Name: proto.String("root"),
397 Field: []*descriptorpb.FieldDescriptorProto{
398 {
399 Name: proto.String("recordID"),
400 Number: proto.Int32(1),
401 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
402 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
403 },
404 {
405 Name: proto.String("recordDetails"),
406 Number: proto.Int32(2),
407 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
408 TypeName: proto.String(".root__recordDetails"),
409 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
410 },
411 },
412 },
413 wantProto2Normalized: &descriptorpb.DescriptorProto{
414 Name: proto.String("root"),
415 Field: []*descriptorpb.FieldDescriptorProto{
416 {
417 Name: proto.String("recordID"),
418 Number: proto.Int32(1),
419 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
420 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
421 },
422 {
423 Name: proto.String("recordDetails"),
424 Number: proto.Int32(2),
425 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
426 TypeName: proto.String("root__recordDetails"),
427 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
428 },
429 },
430 NestedType: []*descriptorpb.DescriptorProto{
431 {
432 Name: proto.String("root__recordDetails"),
433 Field: []*descriptorpb.FieldDescriptorProto{
434 {
435 Name: proto.String("key"),
436 Number: proto.Int32(1),
437 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
438 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
439 },
440 {
441 Name: proto.String("value"),
442 Number: proto.Int32(2),
443 Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(),
444 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
445 },
446 },
447 },
448 },
449 },
450 wantProto3: &descriptorpb.DescriptorProto{
451 Name: proto.String("root"),
452 Field: []*descriptorpb.FieldDescriptorProto{
453 {
454 Name: proto.String("recordID"),
455 Number: proto.Int32(1),
456 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
457 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
458 },
459 {
460 Name: proto.String("recordDetails"),
461 Number: proto.Int32(2),
462 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
463 TypeName: proto.String(".root__recordDetails"),
464 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
465 },
466 },
467 },
468 },
469 {
470
471 description: "nested with duplicate submessage",
472 bq: &storagepb.TableSchema{
473 Fields: []*storagepb.TableFieldSchema{
474 {Name: "curdate", Type: storagepb.TableFieldSchema_DATE, Mode: storagepb.TableFieldSchema_NULLABLE},
475 {
476 Name: "rec1",
477 Type: storagepb.TableFieldSchema_STRUCT,
478 Mode: storagepb.TableFieldSchema_NULLABLE,
479 Fields: []*storagepb.TableFieldSchema{
480 {Name: "userid", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_REQUIRED},
481 {Name: "location", Type: storagepb.TableFieldSchema_GEOGRAPHY, Mode: storagepb.TableFieldSchema_NULLABLE},
482 },
483 },
484 {
485 Name: "rec2",
486 Type: storagepb.TableFieldSchema_STRUCT,
487 Mode: storagepb.TableFieldSchema_NULLABLE,
488 Fields: []*storagepb.TableFieldSchema{
489 {Name: "userid", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_REQUIRED},
490 {Name: "location", Type: storagepb.TableFieldSchema_GEOGRAPHY, Mode: storagepb.TableFieldSchema_NULLABLE},
491 },
492 },
493 },
494 },
495 wantProto2: &descriptorpb.DescriptorProto{
496 Name: proto.String("root"),
497 Field: []*descriptorpb.FieldDescriptorProto{
498 {
499 Name: proto.String("curdate"),
500 Number: proto.Int32(1),
501 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
502 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
503 },
504 {
505 Name: proto.String("rec1"),
506 Number: proto.Int32(2),
507 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
508 TypeName: proto.String(".root__rec1"),
509 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
510 },
511 {
512 Name: proto.String("rec2"),
513 Number: proto.Int32(3),
514 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
515 TypeName: proto.String(".root__rec1"),
516 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
517 },
518 },
519 },
520 wantProto3: &descriptorpb.DescriptorProto{
521 Name: proto.String("root"),
522 Field: []*descriptorpb.FieldDescriptorProto{
523 {
524 Name: proto.String("curdate"),
525 Number: proto.Int32(1),
526 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
527 TypeName: proto.String(".google.protobuf.Int32Value"),
528 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
529 },
530 {
531 Name: proto.String("rec1"),
532 Number: proto.Int32(2),
533 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
534 TypeName: proto.String(".root__rec1"),
535 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
536 },
537 {
538 Name: proto.String("rec2"),
539 Number: proto.Int32(3),
540 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
541 TypeName: proto.String(".root__rec1"),
542 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
543 },
544 },
545 },
546 },
547 {
548 description: "nested with reused submessage in different levels",
549 bq: &storagepb.TableSchema{
550 Fields: []*storagepb.TableFieldSchema{
551 {
552 Name: "reused_inner_struct",
553 Type: storagepb.TableFieldSchema_STRUCT,
554 Mode: storagepb.TableFieldSchema_REQUIRED,
555 Fields: []*storagepb.TableFieldSchema{
556 {
557 Name: "leaf",
558 Type: storagepb.TableFieldSchema_STRING,
559 Mode: storagepb.TableFieldSchema_REQUIRED,
560 },
561 },
562 },
563 {
564 Name: "outer_struct",
565 Type: storagepb.TableFieldSchema_STRUCT,
566 Mode: storagepb.TableFieldSchema_REQUIRED,
567 Fields: []*storagepb.TableFieldSchema{
568 {
569 Name: "another_inner_struct",
570 Type: storagepb.TableFieldSchema_STRUCT,
571 Mode: storagepb.TableFieldSchema_REQUIRED,
572 Fields: []*storagepb.TableFieldSchema{
573 {
574 Name: "another_leaf",
575 Type: storagepb.TableFieldSchema_STRING,
576 Mode: storagepb.TableFieldSchema_REQUIRED,
577 },
578 },
579 },
580 {
581 Name: "reused_inner_struct_one",
582 Type: storagepb.TableFieldSchema_STRUCT,
583 Mode: storagepb.TableFieldSchema_REQUIRED,
584 Fields: []*storagepb.TableFieldSchema{
585 {
586 Name: "leaf",
587 Type: storagepb.TableFieldSchema_STRING,
588 Mode: storagepb.TableFieldSchema_REQUIRED,
589 },
590 },
591 },
592 {
593 Name: "reused_inner_struct_two",
594 Type: storagepb.TableFieldSchema_STRUCT,
595 Mode: storagepb.TableFieldSchema_REQUIRED,
596 Fields: []*storagepb.TableFieldSchema{
597 {
598 Name: "leaf",
599 Type: storagepb.TableFieldSchema_STRING,
600 Mode: storagepb.TableFieldSchema_REQUIRED,
601 },
602 },
603 },
604 },
605 },
606 },
607 },
608 wantProto2: &descriptorpb.DescriptorProto{
609 Name: proto.String("root"),
610 Field: []*descriptorpb.FieldDescriptorProto{
611 {
612 Name: proto.String("reused_inner_struct"),
613 Number: proto.Int32(1),
614 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
615 TypeName: proto.String(".root__reused_inner_struct"),
616 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
617 },
618 {
619 Name: proto.String("outer_struct"),
620 Number: proto.Int32(2),
621 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
622 TypeName: proto.String(".root__outer_struct"),
623 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
624 },
625 },
626 },
627 wantProto2Normalized: &descriptorpb.DescriptorProto{
628 Name: proto.String("root"),
629 Field: []*descriptorpb.FieldDescriptorProto{
630 {
631 Name: proto.String("reused_inner_struct"),
632 Number: proto.Int32(1),
633 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
634 TypeName: proto.String("root__reused_inner_struct"),
635 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
636 },
637 {
638 Name: proto.String("outer_struct"),
639 Number: proto.Int32(2),
640 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
641 TypeName: proto.String("root__outer_struct"),
642 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
643 },
644 },
645 NestedType: []*descriptorpb.DescriptorProto{
646 {
647 Name: proto.String("root__outer_struct"),
648 Field: []*descriptorpb.FieldDescriptorProto{
649 {
650 Name: proto.String("another_inner_struct"),
651 Number: proto.Int32(1),
652 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
653 TypeName: proto.String("root__outer_struct__another_inner_struct"),
654 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
655 },
656 {
657 Name: proto.String("reused_inner_struct_one"),
658 Number: proto.Int32(2),
659 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
660 TypeName: proto.String("root__reused_inner_struct"),
661 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
662 },
663 {
664 Name: proto.String("reused_inner_struct_two"),
665 Number: proto.Int32(3),
666 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
667 TypeName: proto.String("root__reused_inner_struct"),
668 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
669 },
670 },
671 },
672 {
673 Name: proto.String("root__outer_struct__another_inner_struct"),
674 Field: []*descriptorpb.FieldDescriptorProto{
675 {
676 Name: proto.String("another_leaf"),
677 Number: proto.Int32(1),
678 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
679 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
680 },
681 },
682 },
683 {
684 Name: proto.String("root__reused_inner_struct"),
685 Field: []*descriptorpb.FieldDescriptorProto{
686 {
687 Name: proto.String("leaf"),
688 Number: proto.Int32(1),
689 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
690 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
691 },
692 },
693 },
694 },
695 },
696 wantProto3: &descriptorpb.DescriptorProto{
697 Name: proto.String("root"),
698 Field: []*descriptorpb.FieldDescriptorProto{
699 {
700 Name: proto.String("reused_inner_struct"),
701 Number: proto.Int32(1),
702 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
703 TypeName: proto.String(".root__reused_inner_struct"),
704 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
705 },
706 {
707 Name: proto.String("outer_struct"),
708 Number: proto.Int32(2),
709 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
710 TypeName: proto.String(".root__outer_struct"),
711 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
712 },
713 },
714 },
715 },
716 {
717 description: "multiple nesting levels",
718 bq: &storagepb.TableSchema{
719 Fields: []*storagepb.TableFieldSchema{
720 {
721 Name: "outer_struct",
722 Type: storagepb.TableFieldSchema_STRUCT,
723 Mode: storagepb.TableFieldSchema_NULLABLE,
724 Fields: []*storagepb.TableFieldSchema{
725 {
726 Name: "inner_struct",
727 Type: storagepb.TableFieldSchema_STRUCT,
728 Mode: storagepb.TableFieldSchema_NULLABLE,
729 Fields: []*storagepb.TableFieldSchema{
730 {Name: "leaf_one", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_NULLABLE},
731 {Name: "leaf_two", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_NULLABLE},
732 },
733 },
734 },
735 },
736 {
737 Name: "other_field",
738 Type: storagepb.TableFieldSchema_INT64,
739 Mode: storagepb.TableFieldSchema_NULLABLE,
740 },
741 },
742 },
743 wantProto2: &descriptorpb.DescriptorProto{
744 Name: proto.String("root"),
745 Field: []*descriptorpb.FieldDescriptorProto{
746 {
747 Name: proto.String("outer_struct"),
748 Number: proto.Int32(1),
749 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
750 TypeName: proto.String(".root__outer_struct"),
751 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
752 },
753 {
754 Name: proto.String("other_field"),
755 Number: proto.Int32(2),
756 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
757 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
758 },
759 },
760 },
761 wantProto2Normalized: &descriptorpb.DescriptorProto{
762 Name: proto.String("root"),
763 Field: []*descriptorpb.FieldDescriptorProto{
764 {
765 Name: proto.String("outer_struct"),
766 Number: proto.Int32(1),
767 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
768 TypeName: proto.String("root__outer_struct"),
769 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
770 },
771 {
772 Name: proto.String("other_field"),
773 Number: proto.Int32(2),
774 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
775 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
776 },
777 },
778 NestedType: []*descriptorpb.DescriptorProto{
779 {
780 Name: proto.String("root__outer_struct"),
781 Field: []*descriptorpb.FieldDescriptorProto{
782 {
783 Name: proto.String("inner_struct"),
784 Number: proto.Int32(1),
785 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
786 TypeName: proto.String("root__outer_struct__inner_struct"),
787 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
788 },
789 },
790 },
791 {
792 Name: proto.String("root__outer_struct__inner_struct"),
793 Field: []*descriptorpb.FieldDescriptorProto{
794 {
795 Name: proto.String("leaf_one"),
796 Number: proto.Int32(1),
797 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
798 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
799 },
800 {
801 Name: proto.String("leaf_two"),
802 Number: proto.Int32(2),
803 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
804 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
805 },
806 },
807 },
808 },
809 },
810 wantProto3: &descriptorpb.DescriptorProto{
811 Name: proto.String("root"),
812 Field: []*descriptorpb.FieldDescriptorProto{
813 {
814 Name: proto.String("outer_struct"),
815 Number: proto.Int32(1),
816 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
817 TypeName: proto.String(".root__outer_struct"),
818 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
819 },
820 {
821 Name: proto.String("other_field"),
822 Number: proto.Int32(2),
823 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
824 TypeName: proto.String(".google.protobuf.Int64Value"),
825 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
826 },
827 },
828 },
829 },
830 {
831 description: "repeated with packed",
832 bq: &storagepb.TableSchema{
833 Fields: []*storagepb.TableFieldSchema{
834 {Name: "name", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_NULLABLE},
835 {Name: "some_lengths", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_REPEATED},
836 {Name: "nicknames", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_REPEATED},
837 }},
838 wantProto2: &descriptorpb.DescriptorProto{
839 Name: proto.String("root"),
840 Field: []*descriptorpb.FieldDescriptorProto{
841 {
842 Name: proto.String("name"),
843 Number: proto.Int32(1),
844 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
845 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
846 {
847 Name: proto.String("some_lengths"),
848 Number: proto.Int32(2),
849 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
850 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
851 Options: &descriptorpb.FieldOptions{
852 Packed: proto.Bool(true),
853 },
854 },
855 {Name: proto.String("nicknames"), Number: proto.Int32(3), Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(), Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum()},
856 },
857 },
858 },
859 {
860 description: "indirect names",
861 bq: &storagepb.TableSchema{
862 Fields: []*storagepb.TableFieldSchema{
863 {Name: "foo", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_NULLABLE},
864 {Name: "火", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_REQUIRED},
865 {Name: "水_addict", Type: storagepb.TableFieldSchema_BYTES, Mode: storagepb.TableFieldSchema_REPEATED},
866 {Name: "0col", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_NULLABLE},
867 {Name: "funny-name", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_NULLABLE},
868 }},
869 wantProto2: func() *descriptorpb.DescriptorProto {
870 dp := &descriptorpb.DescriptorProto{
871 Name: proto.String("root"),
872 Field: []*descriptorpb.FieldDescriptorProto{
873 {
874 Name: proto.String("foo"),
875 Number: proto.Int32(1),
876 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
877 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
878 {
879 Name: proto.String("col_54Gr"),
880 Number: proto.Int32(2),
881 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
882 Options: &descriptorpb.FieldOptions{},
883 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum()},
884 {
885 Name: proto.String("col_5rC0X2FkZGljdA"),
886 Number: proto.Int32(3),
887 Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(),
888 Options: &descriptorpb.FieldOptions{},
889 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
890 },
891 {
892 Name: proto.String("col_MGNvbA"),
893 Number: proto.Int32(4),
894 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
895 Options: &descriptorpb.FieldOptions{},
896 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
897 {
898 Name: proto.String("col_ZnVubnktbmFtZQ"),
899 Number: proto.Int32(5),
900 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
901 Options: &descriptorpb.FieldOptions{},
902 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum()},
903 },
904 }
905 proto.SetExtension(dp.Field[1].Options, storagepb.E_ColumnName, "火")
906 proto.SetExtension(dp.Field[2].Options, storagepb.E_ColumnName, "水_addict")
907 proto.SetExtension(dp.Field[3].Options, storagepb.E_ColumnName, "0col")
908 proto.SetExtension(dp.Field[4].Options, storagepb.E_ColumnName, "funny-name")
909 return dp
910 }(),
911 },
912 }
913 for _, tc := range testCases {
914 t.Run(tc.description, func(T *testing.T) {
915
916 p2d, err := StorageSchemaToProto2Descriptor(tc.bq, "root")
917 if err != nil {
918 t.Fatalf("failed proto2 conversion: %v", err)
919 }
920
921
922 mDesc, ok := p2d.(protoreflect.MessageDescriptor)
923 if !ok {
924 t.Error("couldn't convert proto2 to messagedescriptor")
925 }
926
927 if tc.wantProto2 != nil {
928 gotDP := protodesc.ToDescriptorProto(mDesc)
929 if diff := cmp.Diff(gotDP, tc.wantProto2, protocmp.Transform()); diff != "" {
930 t.Errorf("proto2: -got, +want:\n%s", diff)
931 }
932 }
933
934 if tc.wantProto2Normalized != nil {
935 gotDP, err := NormalizeDescriptor(mDesc)
936 if err != nil {
937 t.Errorf("failed to normalize: %v", err)
938 }
939 if diff := cmp.Diff(gotDP, tc.wantProto2Normalized, protocmp.Transform()); diff != "" {
940 t.Errorf("proto2normalized: -got, +want:\n%s", diff)
941 }
942 }
943
944 p3d, err := StorageSchemaToProto3Descriptor(tc.bq, "root")
945 if err != nil {
946 t.Fatalf("failed proto3 conversion: %v", err)
947 }
948
949 mDesc, ok = p3d.(protoreflect.MessageDescriptor)
950 if !ok {
951 t.Error("couldn't convert proto3 to messagedescriptor")
952 }
953
954 if tc.wantProto3 != nil {
955 gotDP := protodesc.ToDescriptorProto(mDesc)
956 if diff := cmp.Diff(gotDP, tc.wantProto3, protocmp.Transform()); diff != "" {
957 t.Errorf("proto3: -got, +want:\n%s", diff)
958 }
959 }
960
961 if tc.wantProto3Normalized != nil {
962 gotDP, err := NormalizeDescriptor(mDesc)
963 if err != nil {
964 t.Errorf("failed to normalize: %v", err)
965 }
966 if diff := cmp.Diff(gotDP, tc.wantProto3Normalized, protocmp.Transform()); diff != "" {
967 t.Errorf("proto3normalized: -got, +want:\n%s", diff)
968 }
969 }
970 })
971 }
972 }
973
974 func TestProtoJSONSerialization(t *testing.T) {
975
976 sourceSchema := &storagepb.TableSchema{
977 Fields: []*storagepb.TableFieldSchema{
978 {Name: "record_id", Type: storagepb.TableFieldSchema_INT64, Mode: storagepb.TableFieldSchema_NULLABLE},
979 {
980 Name: "details",
981 Type: storagepb.TableFieldSchema_STRUCT,
982 Mode: storagepb.TableFieldSchema_REPEATED,
983 Fields: []*storagepb.TableFieldSchema{
984 {Name: "key", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_REQUIRED},
985 {Name: "value", Type: storagepb.TableFieldSchema_STRING, Mode: storagepb.TableFieldSchema_NULLABLE},
986 },
987 },
988 },
989 }
990
991 descriptor, err := StorageSchemaToProto2Descriptor(sourceSchema, "root")
992 if err != nil {
993 t.Fatalf("failed to construct descriptor")
994 }
995
996 sampleRecord := []byte(`{"record_id":"12345","details":[{"key":"name","value":"jimmy"},{"key":"title","value":"clown"}]}`)
997
998 messageDescriptor, ok := descriptor.(protoreflect.MessageDescriptor)
999 if !ok {
1000 t.Fatalf("StorageSchemaToDescriptor didn't yield a valid message descriptor, got %T", descriptor)
1001 }
1002
1003
1004 gotOuterDP := protodesc.ToDescriptorProto(messageDescriptor)
1005
1006 innerField := messageDescriptor.Fields().ByName("details")
1007 if innerField == nil {
1008 t.Fatalf("couldn't get inner descriptor for details")
1009 }
1010 gotInnerDP := protodesc.ToDescriptorProto(innerField.Message())
1011
1012 wantOuterDP := &descriptorpb.DescriptorProto{
1013 Name: proto.String("root"),
1014 Field: []*descriptorpb.FieldDescriptorProto{
1015 {
1016 Name: proto.String("record_id"),
1017 Number: proto.Int32(1),
1018 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1019 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1020 },
1021 {
1022 Name: proto.String("details"),
1023 Number: proto.Int32(2),
1024 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1025 TypeName: proto.String(".root__details"),
1026 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1027 },
1028 },
1029 }
1030
1031 wantInnerDP := &descriptorpb.DescriptorProto{
1032 Name: proto.String("root__details"),
1033 Field: []*descriptorpb.FieldDescriptorProto{
1034 {
1035 Name: proto.String("key"),
1036 Number: proto.Int32(1),
1037 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1038 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
1039 },
1040 {
1041 Name: proto.String("value"),
1042 Number: proto.Int32(2),
1043 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1044 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1045 },
1046 },
1047 }
1048
1049 if outerDiff := cmp.Diff(gotOuterDP, wantOuterDP, protocmp.Transform()); outerDiff != "" {
1050 t.Fatalf("DescriptorProto for outer message differs.\n-got, +want:\n%s", outerDiff)
1051 }
1052 if innerDiff := cmp.Diff(gotInnerDP, wantInnerDP, protocmp.Transform()); innerDiff != "" {
1053 t.Fatalf("DescriptorProto for inner message differs.\n-got, +want:\n%s", innerDiff)
1054 }
1055
1056 message := dynamicpb.NewMessage(messageDescriptor)
1057
1058
1059 err = protojson.Unmarshal(sampleRecord, message)
1060 if err != nil {
1061 t.Fatalf("failed to Unmarshal json message: %v", err)
1062 }
1063
1064
1065
1066 options := protojson.MarshalOptions{
1067 UseProtoNames: true,
1068 }
1069 gotBytes, err := options.Marshal(message)
1070 if err != nil {
1071 t.Fatalf("failed to marshal message: %v", err)
1072 }
1073
1074 var got, want interface{}
1075 if err := json.Unmarshal(gotBytes, &got); err != nil {
1076 t.Fatalf("couldn't marshal gotBytes: %v", err)
1077 }
1078 if err := json.Unmarshal(sampleRecord, &want); err != nil {
1079 t.Fatalf("couldn't marshal sampleRecord: %v", err)
1080 }
1081 if !reflect.DeepEqual(got, want) {
1082 t.Fatalf("mismatched json: got\n%q\nwant\n%q", gotBytes, sampleRecord)
1083 }
1084
1085 }
1086
1087 func TestNormalizeDescriptor(t *testing.T) {
1088 testCases := []struct {
1089 description string
1090 in protoreflect.MessageDescriptor
1091 wantErr bool
1092 want *descriptorpb.DescriptorProto
1093 }{
1094 {
1095 description: "nil",
1096 in: nil,
1097 wantErr: true,
1098 },
1099 {
1100 description: "AllSupportedTypes",
1101 in: (&testdata.AllSupportedTypes{}).ProtoReflect().Descriptor(),
1102 want: &descriptorpb.DescriptorProto{
1103 Name: proto.String("testdata_AllSupportedTypes"),
1104 Field: []*descriptorpb.FieldDescriptorProto{
1105 {
1106 Name: proto.String("int32_value"),
1107 JsonName: proto.String("int32Value"),
1108 Number: proto.Int32(1),
1109 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
1110 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1111 },
1112 {
1113 Name: proto.String("int64_value"),
1114 JsonName: proto.String("int64Value"),
1115 Number: proto.Int32(2),
1116 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1117 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1118 },
1119 {
1120 Name: proto.String("uint32_value"),
1121 JsonName: proto.String("uint32Value"),
1122 Number: proto.Int32(3),
1123 Type: descriptorpb.FieldDescriptorProto_TYPE_UINT32.Enum(),
1124 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1125 },
1126 {
1127 Name: proto.String("uint64_value"),
1128 JsonName: proto.String("uint64Value"),
1129 Number: proto.Int32(4),
1130 Type: descriptorpb.FieldDescriptorProto_TYPE_UINT64.Enum(),
1131 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1132 },
1133 {
1134 Name: proto.String("float_value"),
1135 JsonName: proto.String("floatValue"),
1136 Number: proto.Int32(5),
1137 Type: descriptorpb.FieldDescriptorProto_TYPE_FLOAT.Enum(),
1138 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1139 },
1140 {
1141 Name: proto.String("double_value"),
1142 JsonName: proto.String("doubleValue"),
1143 Number: proto.Int32(6),
1144 Type: descriptorpb.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
1145 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1146 },
1147 {
1148 Name: proto.String("bool_value"),
1149 JsonName: proto.String("boolValue"),
1150 Number: proto.Int32(7),
1151 Type: descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
1152 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1153 },
1154 {
1155 Name: proto.String("enum_value"),
1156 JsonName: proto.String("enumValue"),
1157 TypeName: proto.String("testdata_TestEnum_E.TestEnum"),
1158 Number: proto.Int32(8),
1159 Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
1160 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1161 },
1162 {
1163 Name: proto.String("string_value"),
1164 JsonName: proto.String("stringValue"),
1165 Number: proto.Int32(9),
1166 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1167 Label: descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
1168 },
1169 {
1170 Name: proto.String("fixed64_value"),
1171 JsonName: proto.String("fixed64Value"),
1172 Number: proto.Int32(10),
1173 Type: descriptorpb.FieldDescriptorProto_TYPE_FIXED64.Enum(),
1174 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1175 },
1176 },
1177 NestedType: []*descriptorpb.DescriptorProto{
1178 {
1179 Name: proto.String("testdata_TestEnum_E"),
1180 EnumType: []*descriptorpb.EnumDescriptorProto{
1181 {
1182 Name: proto.String("TestEnum"),
1183 Value: []*descriptorpb.EnumValueDescriptorProto{
1184 {
1185 Name: proto.String("TestEnum0"),
1186 Number: proto.Int32(0),
1187 },
1188 {
1189 Name: proto.String("TestEnum1"),
1190 Number: proto.Int32(1),
1191 },
1192 },
1193 },
1194 },
1195 },
1196 },
1197 },
1198 },
1199 {
1200 description: "ContainsRecursive",
1201 in: (&testdata.ContainsRecursive{}).ProtoReflect().Descriptor(),
1202 wantErr: true,
1203 },
1204 {
1205 description: "RecursiveTypeTopMessage",
1206 in: (&testdata.RecursiveTypeTopMessage{}).ProtoReflect().Descriptor(),
1207 wantErr: true,
1208 },
1209 {
1210 description: "ComplexType",
1211 in: (&testdata.ComplexType{}).ProtoReflect().Descriptor(),
1212 want: &descriptorpb.DescriptorProto{
1213 Name: proto.String("testdata_ComplexType"),
1214 Field: []*descriptorpb.FieldDescriptorProto{
1215 {
1216 Name: proto.String("nested_repeated_type"),
1217 JsonName: proto.String("nestedRepeatedType"),
1218 Number: proto.Int32(1),
1219 TypeName: proto.String("testdata_NestedType"),
1220 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1221 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1222 },
1223 {
1224 Name: proto.String("inner_type"),
1225 JsonName: proto.String("innerType"),
1226 Number: proto.Int32(2),
1227 TypeName: proto.String("testdata_InnerType"),
1228 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1229 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1230 },
1231 {
1232 Name: proto.String("range_type"),
1233 JsonName: proto.String("rangeType"),
1234 Number: proto.Int32(3),
1235 TypeName: proto.String("testdata_RangeTypeTimestamp"),
1236 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1237 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1238 },
1239 },
1240 NestedType: []*descriptorpb.DescriptorProto{
1241 {
1242 Name: proto.String("testdata_InnerType"),
1243 Field: []*descriptorpb.FieldDescriptorProto{
1244 {
1245 Name: proto.String("value"),
1246 JsonName: proto.String("value"),
1247 Number: proto.Int32(1),
1248 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1249 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1250 },
1251 },
1252 },
1253 {
1254 Name: proto.String("testdata_NestedType"),
1255 Field: []*descriptorpb.FieldDescriptorProto{
1256 {
1257 Name: proto.String("inner_type"),
1258 JsonName: proto.String("innerType"),
1259 Number: proto.Int32(1),
1260 TypeName: proto.String("testdata_InnerType"),
1261 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1262 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1263 },
1264 },
1265 },
1266 {
1267 Name: proto.String("testdata_RangeTypeTimestamp"),
1268 Field: []*descriptorpb.FieldDescriptorProto{
1269 {
1270 Name: proto.String("start"),
1271 JsonName: proto.String("start"),
1272 Number: proto.Int32(1),
1273 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1274 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1275 },
1276 {
1277 Name: proto.String("end"),
1278 JsonName: proto.String("end"),
1279 Number: proto.Int32(2),
1280 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1281 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1282 },
1283 },
1284 },
1285 },
1286 },
1287 },
1288 {
1289 description: "WithWellKnownTypes",
1290 in: (&testdata.WithWellKnownTypes{}).ProtoReflect().Descriptor(),
1291 want: &descriptorpb.DescriptorProto{
1292 Name: proto.String("testdata_WithWellKnownTypes"),
1293 Field: []*descriptorpb.FieldDescriptorProto{
1294 {
1295 Name: proto.String("int64_value"),
1296 JsonName: proto.String("int64Value"),
1297 Number: proto.Int32(1),
1298 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1299 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1300 },
1301 {
1302 Name: proto.String("wrapped_int64"),
1303 JsonName: proto.String("wrappedInt64"),
1304 Number: proto.Int32(2),
1305 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1306 TypeName: proto.String("google_protobuf_Int64Value"),
1307 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1308 },
1309 {
1310 Name: proto.String("string_value"),
1311 JsonName: proto.String("stringValue"),
1312 Number: proto.Int32(3),
1313 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1314 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1315 },
1316 {
1317 Name: proto.String("wrapped_string"),
1318 JsonName: proto.String("wrappedString"),
1319 Number: proto.Int32(4),
1320 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1321 TypeName: proto.String("google_protobuf_StringValue"),
1322 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1323 },
1324 },
1325 NestedType: []*descriptorpb.DescriptorProto{
1326 {
1327 Name: proto.String("google_protobuf_Int64Value"),
1328 Field: []*descriptorpb.FieldDescriptorProto{
1329 {
1330 Name: proto.String("value"),
1331 JsonName: proto.String("value"),
1332 Number: proto.Int32(1),
1333 DefaultValue: proto.String("0"),
1334 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1335 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1336 },
1337 },
1338 },
1339 {
1340 Name: proto.String("google_protobuf_StringValue"),
1341 Field: []*descriptorpb.FieldDescriptorProto{
1342 {
1343 Name: proto.String("value"),
1344 JsonName: proto.String("value"),
1345 Number: proto.Int32(1),
1346 DefaultValue: proto.String(""),
1347 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1348 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1349 },
1350 },
1351 },
1352 },
1353 },
1354 },
1355 {
1356 description: "WithOneOf",
1357 in: (&testdata.WithOneOf{}).ProtoReflect().Descriptor(),
1358 want: &descriptorpb.DescriptorProto{
1359 Name: proto.String("testdata_WithOneOf"),
1360 Field: []*descriptorpb.FieldDescriptorProto{
1361 {
1362 Name: proto.String("int32_value"),
1363 JsonName: proto.String("int32Value"),
1364 Number: proto.Int32(1),
1365 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
1366 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1367 },
1368 {
1369 Name: proto.String("string_value"),
1370 JsonName: proto.String("stringValue"),
1371 Number: proto.Int32(2),
1372 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1373 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1374 },
1375 {
1376 Name: proto.String("double_value"),
1377 JsonName: proto.String("doubleValue"),
1378 Number: proto.Int32(3),
1379 Type: descriptorpb.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
1380 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1381 },
1382 },
1383 },
1384 },
1385 {
1386 description: "WithProto3Optional",
1387 in: (&testdata.SimpleMessageProto3WithOptional{}).ProtoReflect().Descriptor(),
1388 want: &descriptorpb.DescriptorProto{
1389 Name: proto.String("testdata_SimpleMessageProto3WithOptional"),
1390 Field: []*descriptorpb.FieldDescriptorProto{
1391 {
1392 Name: proto.String("name"),
1393 JsonName: proto.String("name"),
1394 Number: proto.Int32(1),
1395 DefaultValue: proto.String(""),
1396 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1397 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1398 },
1399 {
1400 Name: proto.String("value"),
1401 JsonName: proto.String("value"),
1402 Number: proto.Int32(2),
1403 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1404 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1405 },
1406 },
1407 },
1408 },
1409 {
1410 description: "WithProto3Defaults",
1411 in: (&testdata.ValidationP3Defaults{}).ProtoReflect().Descriptor(),
1412 want: &descriptorpb.DescriptorProto{
1413 Name: proto.String("testdata_ValidationP3Defaults"),
1414 Field: []*descriptorpb.FieldDescriptorProto{
1415 {
1416 Name: proto.String("double_field"),
1417 JsonName: proto.String("doubleField"),
1418 Number: proto.Int32(1),
1419 Type: descriptorpb.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
1420 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1421 DefaultValue: proto.String("0"),
1422 },
1423 {
1424 Name: proto.String("float_field"),
1425 JsonName: proto.String("floatField"),
1426 Number: proto.Int32(2),
1427 Type: descriptorpb.FieldDescriptorProto_TYPE_FLOAT.Enum(),
1428 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1429 DefaultValue: proto.String("0"),
1430 },
1431 {
1432 Name: proto.String("int32_field"),
1433 JsonName: proto.String("int32Field"),
1434 Number: proto.Int32(3),
1435 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
1436 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1437 DefaultValue: proto.String("0"),
1438 },
1439 {
1440 Name: proto.String("int64_field"),
1441 JsonName: proto.String("int64Field"),
1442 Number: proto.Int32(4),
1443 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1444 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1445 DefaultValue: proto.String("0"),
1446 },
1447 {
1448 Name: proto.String("uint32_field"),
1449 JsonName: proto.String("uint32Field"),
1450 Number: proto.Int32(5),
1451 Type: descriptorpb.FieldDescriptorProto_TYPE_UINT32.Enum(),
1452 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1453 DefaultValue: proto.String("0"),
1454 },
1455 {
1456 Name: proto.String("sint32_field"),
1457 JsonName: proto.String("sint32Field"),
1458 Number: proto.Int32(7),
1459 Type: descriptorpb.FieldDescriptorProto_TYPE_SINT32.Enum(),
1460 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1461 DefaultValue: proto.String("0"),
1462 },
1463 {
1464 Name: proto.String("sint64_field"),
1465 JsonName: proto.String("sint64Field"),
1466 Number: proto.Int32(8),
1467 Type: descriptorpb.FieldDescriptorProto_TYPE_SINT64.Enum(),
1468 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1469 DefaultValue: proto.String("0"),
1470 },
1471 {
1472 Name: proto.String("fixed32_field"),
1473 JsonName: proto.String("fixed32Field"),
1474 Number: proto.Int32(9),
1475 Type: descriptorpb.FieldDescriptorProto_TYPE_FIXED32.Enum(),
1476 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1477 DefaultValue: proto.String("0"),
1478 },
1479 {
1480 Name: proto.String("sfixed32_field"),
1481 JsonName: proto.String("sfixed32Field"),
1482 Number: proto.Int32(11),
1483 Type: descriptorpb.FieldDescriptorProto_TYPE_SFIXED32.Enum(),
1484 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1485 DefaultValue: proto.String("0"),
1486 },
1487 {
1488 Name: proto.String("sfixed64_field"),
1489 JsonName: proto.String("sfixed64Field"),
1490 Number: proto.Int32(12),
1491 Type: descriptorpb.FieldDescriptorProto_TYPE_SFIXED64.Enum(),
1492 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1493 DefaultValue: proto.String("0"),
1494 },
1495 {
1496 Name: proto.String("bool_field"),
1497 JsonName: proto.String("boolField"),
1498 Number: proto.Int32(13),
1499 Type: descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
1500 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1501 DefaultValue: proto.String("false"),
1502 },
1503 {
1504 Name: proto.String("string_field"),
1505 JsonName: proto.String("stringField"),
1506 Number: proto.Int32(14),
1507 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1508 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1509 DefaultValue: proto.String(""),
1510 },
1511 {
1512 Name: proto.String("bytes_field"),
1513 JsonName: proto.String("bytesField"),
1514 Number: proto.Int32(15),
1515 Type: descriptorpb.FieldDescriptorProto_TYPE_BYTES.Enum(),
1516 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1517 DefaultValue: proto.String(""),
1518 },
1519 {
1520 Name: proto.String("enum_field"),
1521 JsonName: proto.String("enumField"),
1522 Number: proto.Int32(16),
1523 Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
1524 TypeName: proto.String("testdata_Proto3ExampleEnum_E.Proto3ExampleEnum"),
1525 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1526 DefaultValue: proto.String("P3_UNDEFINED"),
1527 },
1528 },
1529 NestedType: []*descriptorpb.DescriptorProto{
1530 {
1531 Name: proto.String("testdata_Proto3ExampleEnum_E"),
1532 EnumType: []*descriptorpb.EnumDescriptorProto{
1533 {
1534 Name: proto.String("Proto3ExampleEnum"),
1535 Value: []*descriptorpb.EnumValueDescriptorProto{
1536 {
1537 Name: proto.String("P3_UNDEFINED"),
1538 Number: proto.Int32(0),
1539 },
1540 {
1541 Name: proto.String("P3_THING"),
1542 Number: proto.Int32(1),
1543 },
1544 {
1545 Name: proto.String("P3_OTHER_THING"),
1546 Number: proto.Int32(2),
1547 },
1548 {
1549 Name: proto.String("P3_THIRD_THING"),
1550 Number: proto.Int32(3),
1551 },
1552 },
1553 },
1554 },
1555 },
1556 },
1557 },
1558 },
1559 {
1560 description: "WithExternalEnum",
1561 in: (&testdata.ExternalEnumMessage{}).ProtoReflect().Descriptor(),
1562 want: &descriptorpb.DescriptorProto{
1563 Name: proto.String("testdata_ExternalEnumMessage"),
1564 Field: []*descriptorpb.FieldDescriptorProto{
1565 {
1566 Name: proto.String("msg_a"),
1567 JsonName: proto.String("msgA"),
1568 Number: proto.Int32(1),
1569 TypeName: proto.String("testdata_EnumMsgA"),
1570 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1571 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1572 },
1573 {
1574 Name: proto.String("msg_b"),
1575 JsonName: proto.String("msgB"),
1576 Number: proto.Int32(2),
1577 TypeName: proto.String("testdata_EnumMsgB"),
1578 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1579 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1580 },
1581 },
1582 NestedType: []*descriptorpb.DescriptorProto{
1583 {
1584 Name: proto.String("testdata_EnumMsgA"),
1585 Field: []*descriptorpb.FieldDescriptorProto{
1586 {
1587 Name: proto.String("foo"),
1588 JsonName: proto.String("foo"),
1589 Number: proto.Int32(1),
1590 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1591 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1592 },
1593 {
1594 Name: proto.String("bar"),
1595 JsonName: proto.String("bar"),
1596 Number: proto.Int32(2),
1597 Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
1598 TypeName: proto.String("testdata_ExtEnum_E.ExtEnum"),
1599 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1600 },
1601 },
1602 },
1603 {
1604 Name: proto.String("testdata_EnumMsgB"),
1605 Field: []*descriptorpb.FieldDescriptorProto{
1606 {
1607 Name: proto.String("baz"),
1608 JsonName: proto.String("baz"),
1609 Number: proto.Int32(1),
1610 Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
1611 TypeName: proto.String("testdata_ExtEnum_E.ExtEnum"),
1612 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1613 },
1614 },
1615 },
1616 {
1617 Name: proto.String("testdata_ExtEnum_E"),
1618 EnumType: []*descriptorpb.EnumDescriptorProto{
1619 {
1620 Name: proto.String("ExtEnum"),
1621 Value: []*descriptorpb.EnumValueDescriptorProto{
1622 {
1623 Name: proto.String("UNDEFINED"),
1624 Number: proto.Int32(0),
1625 },
1626 {
1627 Name: proto.String("THING"),
1628 Number: proto.Int32(1),
1629 },
1630 {
1631 Name: proto.String("OTHER_THING"),
1632 Number: proto.Int32(2),
1633 },
1634 },
1635 },
1636 },
1637 },
1638 },
1639 },
1640 },
1641 {
1642 description: "OutOfOrderDefinitionProto2",
1643 in: (&testdata.OutOfOrderDefinitionProto2{}).ProtoReflect().Descriptor(),
1644 want: &descriptorpb.DescriptorProto{
1645 Name: proto.String("testdata_OutOfOrderDefinitionProto2"),
1646 Field: []*descriptorpb.FieldDescriptorProto{
1647 {
1648 Name: proto.String("s1"),
1649 JsonName: proto.String("s1"),
1650 Number: proto.Int32(1),
1651 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1652 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1653 },
1654 {
1655 Name: proto.String("s2"),
1656 JsonName: proto.String("s2"),
1657 Number: proto.Int32(2),
1658 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1659 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1660 },
1661 {
1662 Name: proto.String("s3"),
1663 JsonName: proto.String("s3"),
1664 Number: proto.Int32(3),
1665 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1666 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1667 },
1668 {
1669 Name: proto.String("enum1"),
1670 JsonName: proto.String("enum1"),
1671 Number: proto.Int32(4),
1672 Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
1673 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1674 TypeName: proto.String("testdata_OutOfOrderDefinitionProto2_OutOfOrderEnum_E.OutOfOrderEnum"),
1675 },
1676 {
1677 Name: proto.String("enum2"),
1678 JsonName: proto.String("enum2"),
1679 Number: proto.Int32(5),
1680 Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
1681 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1682 TypeName: proto.String("testdata_OutOfOrderDefinitionProto2_OutOfOrderEnum_E.OutOfOrderEnum"),
1683 },
1684 {
1685 Name: proto.String("msg6"),
1686 JsonName: proto.String("msg6"),
1687 Number: proto.Int32(6),
1688 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1689 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1690 TypeName: proto.String("testdata_SimpleMessageProto2"),
1691 },
1692 {
1693 Name: proto.String("msg7"),
1694 JsonName: proto.String("msg7"),
1695 Number: proto.Int32(7),
1696 Type: descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
1697 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1698 TypeName: proto.String("testdata_SimpleMessageProto2"),
1699 },
1700 },
1701 NestedType: []*descriptorpb.DescriptorProto{
1702 {
1703 Name: proto.String("testdata_OutOfOrderDefinitionProto2_OutOfOrderEnum_E"),
1704 EnumType: []*descriptorpb.EnumDescriptorProto{
1705 {
1706 Name: proto.String("OutOfOrderEnum"),
1707 Value: []*descriptorpb.EnumValueDescriptorProto{
1708 {
1709 Name: proto.String("E1"),
1710 Number: proto.Int32(1),
1711 },
1712 {
1713 Name: proto.String("E2"),
1714 Number: proto.Int32(2),
1715 },
1716 {
1717 Name: proto.String("E3"),
1718 Number: proto.Int32(3),
1719 },
1720 },
1721 },
1722 },
1723 },
1724 {
1725 Name: proto.String("testdata_SimpleMessageProto2"),
1726 Field: []*descriptorpb.FieldDescriptorProto{
1727 {
1728 Name: proto.String("name"),
1729 JsonName: proto.String("name"),
1730 Number: proto.Int32(1),
1731 Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
1732 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1733 },
1734 {
1735 Name: proto.String("value"),
1736 JsonName: proto.String("value"),
1737 Number: proto.Int32(2),
1738 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1739 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1740 },
1741 },
1742 },
1743 },
1744 },
1745 },
1746 {
1747 description: "ValidationP3PackedRepeated",
1748 in: (&testdata.ValidationP3PackedRepeated{}).ProtoReflect().Descriptor(),
1749 want: &descriptorpb.DescriptorProto{
1750 Name: proto.String("testdata_ValidationP3PackedRepeated"),
1751 Field: []*descriptorpb.FieldDescriptorProto{
1752 {
1753 Name: proto.String("id"),
1754 JsonName: proto.String("id"),
1755 Number: proto.Int32(1),
1756 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1757 Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
1758 },
1759 {
1760 Name: proto.String("double_repeated"),
1761 JsonName: proto.String("doubleRepeated"),
1762 Number: proto.Int32(2),
1763 Type: descriptorpb.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
1764 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1765 },
1766 {
1767 Name: proto.String("float_repeated"),
1768 JsonName: proto.String("floatRepeated"),
1769 Number: proto.Int32(3),
1770 Type: descriptorpb.FieldDescriptorProto_TYPE_FLOAT.Enum(),
1771 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1772 },
1773 {
1774 Name: proto.String("int32_repeated"),
1775 JsonName: proto.String("int32Repeated"),
1776 Number: proto.Int32(4),
1777 Type: descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
1778 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1779 },
1780 {
1781 Name: proto.String("int64_repeated"),
1782 JsonName: proto.String("int64Repeated"),
1783 Number: proto.Int32(5),
1784 Type: descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
1785 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1786 },
1787 {
1788 Name: proto.String("uint32_repeated"),
1789 JsonName: proto.String("uint32Repeated"),
1790 Number: proto.Int32(6),
1791 Type: descriptorpb.FieldDescriptorProto_TYPE_UINT32.Enum(),
1792 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1793 },
1794 {
1795 Name: proto.String("sint32_repeated"),
1796 JsonName: proto.String("sint32Repeated"),
1797 Number: proto.Int32(7),
1798 Type: descriptorpb.FieldDescriptorProto_TYPE_SINT32.Enum(),
1799 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1800 },
1801 {
1802 Name: proto.String("sint64_repeated"),
1803 JsonName: proto.String("sint64Repeated"),
1804 Number: proto.Int32(8),
1805 Type: descriptorpb.FieldDescriptorProto_TYPE_SINT64.Enum(),
1806 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1807 },
1808 {
1809 Name: proto.String("fixed32_repeated"),
1810 JsonName: proto.String("fixed32Repeated"),
1811 Number: proto.Int32(9),
1812 Type: descriptorpb.FieldDescriptorProto_TYPE_FIXED32.Enum(),
1813 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1814 },
1815 {
1816 Name: proto.String("sfixed32_repeated"),
1817 JsonName: proto.String("sfixed32Repeated"),
1818 Number: proto.Int32(10),
1819 Type: descriptorpb.FieldDescriptorProto_TYPE_SFIXED32.Enum(),
1820 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1821 },
1822 {
1823 Name: proto.String("sfixed64_repeated"),
1824 JsonName: proto.String("sfixed64Repeated"),
1825 Number: proto.Int32(11),
1826 Type: descriptorpb.FieldDescriptorProto_TYPE_SFIXED64.Enum(),
1827 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1828 },
1829
1830 {
1831 Name: proto.String("bool_repeated"),
1832 JsonName: proto.String("boolRepeated"),
1833 Number: proto.Int32(12),
1834 Type: descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
1835 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1836 },
1837 {
1838 Name: proto.String("enum_repeated"),
1839 JsonName: proto.String("enumRepeated"),
1840 Number: proto.Int32(13),
1841 Type: descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
1842 TypeName: proto.String("testdata_Proto3ExampleEnum_E.Proto3ExampleEnum"),
1843 Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
1844 },
1845 },
1846 NestedType: []*descriptorpb.DescriptorProto{
1847 {
1848 Name: proto.String("testdata_Proto3ExampleEnum_E"),
1849 EnumType: []*descriptorpb.EnumDescriptorProto{
1850 {
1851 Name: proto.String("Proto3ExampleEnum"),
1852 Value: []*descriptorpb.EnumValueDescriptorProto{
1853 {
1854 Name: proto.String("P3_UNDEFINED"),
1855 Number: proto.Int32(0),
1856 },
1857 {
1858 Name: proto.String("P3_THING"),
1859 Number: proto.Int32(1),
1860 },
1861 {
1862 Name: proto.String("P3_OTHER_THING"),
1863 Number: proto.Int32(2),
1864 },
1865 {
1866 Name: proto.String("P3_THIRD_THING"),
1867 Number: proto.Int32(3),
1868 },
1869 },
1870 },
1871 },
1872 },
1873 },
1874 },
1875 },
1876 }
1877
1878 for _, tc := range testCases {
1879 gotDP, err := NormalizeDescriptor(tc.in)
1880
1881 if tc.wantErr && err == nil {
1882 t.Errorf("%s: wanted err but got success", tc.description)
1883 continue
1884 }
1885 if !tc.wantErr && err != nil {
1886 t.Errorf("%s: wanted success, got err: %v", tc.description, err)
1887 continue
1888 }
1889 if diff := cmp.Diff(gotDP, tc.want, protocmp.Transform()); diff != "" {
1890 t.Errorf("%s: -got, +want:\n%s", tc.description, diff)
1891 }
1892 }
1893 }
1894
View as plain text