1// Copyright 2019 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package main 6 7import ( 8 "testing" 9 10 "google.golang.org/protobuf/proto" 11 "google.golang.org/protobuf/reflect/protoreflect" 12 13 retentionpb "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/retention" 14) 15 16func TestFileOptionRetention(t *testing.T) { 17 options := retentionpb.File_cmd_protoc_gen_go_testdata_retention_retention_proto.Options() 18 tests := []struct { 19 name string 20 ext protoreflect.ExtensionType 21 wantField bool 22 wantValue int32 23 }{ 24 { 25 name: "imported_plain_option", 26 ext: retentionpb.E_ImportedPlainOption, 27 wantField: true, 28 wantValue: 1, 29 }, 30 { 31 name: "imported_runtime_option", 32 ext: retentionpb.E_ImportedRuntimeRetentionOption, 33 wantField: true, 34 wantValue: 2, 35 }, 36 { 37 name: "imported_source_option", 38 ext: retentionpb.E_ImportedSourceRetentionOption, 39 wantField: false, 40 wantValue: 0, 41 }, 42 { 43 name: "plain_option", 44 ext: retentionpb.E_PlainOption, 45 wantField: true, 46 wantValue: 1, 47 }, 48 { 49 name: "runtime_option", 50 ext: retentionpb.E_RuntimeRetentionOption, 51 wantField: true, 52 wantValue: 2, 53 }, 54 { 55 name: "source_option", 56 ext: retentionpb.E_SourceRetentionOption, 57 wantField: false, 58 wantValue: 0, 59 }, 60 } 61 62 for _, test := range tests { 63 if test.wantField != proto.HasExtension(options, test.ext) { 64 t.Errorf("HasExtension(%s): got %v, want %v", test.name, proto.HasExtension(options, test.ext), test.wantField) 65 } 66 if test.wantValue != proto.GetExtension(options, test.ext).(int32) { 67 t.Errorf("GetExtension(%s): got %d, want %d", test.name, proto.GetExtension(options, test.ext).(int32), test.wantValue) 68 } 69 } 70} 71 72func TestAllEntitiesWithMessageOption(t *testing.T) { 73 file := retentionpb.File_cmd_protoc_gen_go_testdata_retention_retention_proto 74 verifyDescriptorOptions(t, string(file.Name()), file.Options()) 75 verifyEnums(t, file.Enums()) 76 verifyMessages(t, file.Messages()) 77 verifyExtensions(t, file.Extensions()) 78 verifyServices(t, file.Services()) 79} 80 81func verifyExtensions(t *testing.T, extensions protoreflect.ExtensionDescriptors) { 82 t.Helper() 83 for i := 0; i < extensions.Len(); i++ { 84 verifyDescriptorOptions(t, string(extensions.Get(i).Name()), extensions.Get(i).Options()) 85 } 86} 87 88func verifyMessages(t *testing.T, messages protoreflect.MessageDescriptors) { 89 t.Helper() 90 for i := 0; i < messages.Len(); i++ { 91 verifyDescriptorOptions(t, string(messages.Get(i).Name()), messages.Get(i).Options()) 92 verifyEnums(t, messages.Get(i).Enums()) 93 verifyMessages(t, messages.Get(i).Messages()) 94 verifyExtensions(t, messages.Get(i).Extensions()) 95 verifyFields(t, messages.Get(i).Fields()) 96 } 97} 98 99func verifyFields(t *testing.T, fields protoreflect.FieldDescriptors) { 100 t.Helper() 101 for i := 0; i < fields.Len(); i++ { 102 verifyDescriptorOptions(t, string(fields.Get(i).Name()), fields.Get(i).Options()) 103 } 104} 105 106func verifyEnums(t *testing.T, enums protoreflect.EnumDescriptors) { 107 t.Helper() 108 for i := 0; i < enums.Len(); i++ { 109 verifyDescriptorOptions(t, string(enums.Get(i).Name()), enums.Get(i).Options()) 110 verifyEnumValues(t, enums.Get(i).Values()) 111 } 112} 113 114func verifyEnumValues(t *testing.T, values protoreflect.EnumValueDescriptors) { 115 t.Helper() 116 for i := 0; i < values.Len(); i++ { 117 verifyDescriptorOptions(t, string(values.Get(i).Name()), values.Get(i).Options()) 118 } 119} 120 121func verifyServices(t *testing.T, services protoreflect.ServiceDescriptors) { 122 t.Helper() 123 for i := 0; i < services.Len(); i++ { 124 verifyDescriptorOptions(t, string(services.Get(i).Name()), services.Get(i).Options()) 125 verifyMethods(t, services.Get(i).Methods()) 126 } 127} 128 129func verifyMethods(t *testing.T, methods protoreflect.MethodDescriptors) { 130 t.Helper() 131 for i := 0; i < methods.Len(); i++ { 132 verifyDescriptorOptions(t, string(methods.Get(i).Name()), methods.Get(i).Options()) 133 } 134} 135 136func verifyDescriptorOptions(t *testing.T, entity string, options protoreflect.ProtoMessage) { 137 t.Helper() 138 options.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { 139 maybeVerifyOption(t, fd, v) 140 return true 141 }) 142} 143 144func maybeVerifyOption(t *testing.T, fd protoreflect.FieldDescriptor, v protoreflect.Value) { 145 t.Helper() 146 if fd.Kind() == protoreflect.MessageKind && string(fd.Message().FullName()) == "goproto.proto.testretention.OptionsMessage" { 147 if fd.IsList() { 148 for i := 0; i < v.List().Len(); i++ { 149 verifyOptionsMessage(t, string(fd.FullName()), v.List().Get(i).Message().Interface().(*retentionpb.OptionsMessage)) 150 } 151 } else { 152 verifyOptionsMessage(t, string(fd.FullName()), v.Message().Interface().(*retentionpb.OptionsMessage)) 153 } 154 } 155} 156 157func verifyOptionsMessage(t *testing.T, entity string, msg *retentionpb.OptionsMessage) { 158 t.Helper() 159 if msg.PlainField == nil { 160 t.Errorf("%s.OptionsMessage.HasField(plain_field): got false, want true", entity) 161 } 162 if msg.GetPlainField() != 1 { 163 t.Errorf("%s.OptionsMessage.GetField(plain_field): got %d, want 1", entity, msg.GetPlainField()) 164 } 165 if msg.RuntimeRetentionField == nil { 166 t.Errorf("%s.OptionsMessage.HasField(runtime_retention_field): got false, want true", entity) 167 } 168 if msg.GetRuntimeRetentionField() != 2 { 169 t.Errorf("%s.OptionsMessage.GetField(runtime_retention_field): got %d, want 2", entity, msg.GetRuntimeRetentionField()) 170 } 171 if msg.SourceRetentionField != nil { 172 t.Errorf("%s.OptionsMessage.HasField(source_retention_field): got true, want false", entity) 173 } 174 if msg.GetSourceRetentionField() != 0 { 175 // Checking that we get 0 even though this was set to 3 in the source file 176 t.Errorf("%s.OptionsMessage.GetField(source_retention_field): got %d, want 0", entity, msg.GetSourceRetentionField()) 177 } 178} 179