• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2008 Google Inc.  All rights reserved.
4 //
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file or at
7 // https://developers.google.com/open-source/licenses/bsd
8 #endregion
9 
10 using Google.Protobuf.Reflection;
11 using NUnit.Framework;
12 using Pb;
13 using static Google.Protobuf.Reflection.FieldDescriptorProto.Types;
14 using Type = Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type;
15 
16 namespace Google.Protobuf.Test.Reflection;
17 
18 public class FeatureInheritanceTest
19 {
20     // Note: there's no test for file defaults, as we don't have the same access to modify the
21     // global defaults in C# that exists in Java.
22 
23     [Test]
FileOverrides()24     public void FileOverrides()
25     {
26         var fileProto = CreateFileProto();
27         SetTestFeature(fileProto, 3);
28         var fileDescriptor = Build(fileProto);
29         Assert.AreEqual(3, GetTestFeature(fileDescriptor.Features));
30     }
31 
32     [Test]
FileMessageInherit()33     public void FileMessageInherit()
34     {
35         var fileProto = CreateFileProto();
36         SetTestFeature(fileProto, 3);
37         var fileDescriptor = Build(fileProto);
38         Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Features));
39     }
40 
41     [Test]
FileMessageOverride()42     public void FileMessageOverride()
43     {
44         var fileProto = CreateFileProto();
45         SetTestFeature(fileProto, 3);
46         SetTestFeature(fileProto.MessageType[0], 5);
47         var fileDescriptor = Build(fileProto);
48         Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Features));
49     }
50 
51     [Test]
FileEnumInherit()52     public void FileEnumInherit()
53     {
54         var fileProto = CreateFileProto();
55         SetTestFeature(fileProto, 3);
56         var fileDescriptor = Build(fileProto);
57         Assert.AreEqual(3, GetTestFeature(fileDescriptor.EnumTypes[0].Features));
58     }
59 
60     [Test]
FileEnumOverride()61     public void FileEnumOverride()
62     {
63         var fileProto = CreateFileProto();
64         SetTestFeature(fileProto, 3);
65         SetTestFeature(fileProto.EnumType[0], 5);
66         var fileDescriptor = Build(fileProto);
67         Assert.AreEqual(5, GetTestFeature(fileDescriptor.EnumTypes[0].Features));
68     }
69 
70     [Test]
FileExtensionInherit()71     public void FileExtensionInherit()
72     {
73         var fileProto = CreateFileProto();
74         SetTestFeature(fileProto, 3);
75         var fileDescriptor = Build(fileProto);
76         Assert.AreEqual(3, GetTestFeature(fileDescriptor.EnumTypes[0].Features));
77     }
78 
79     [Test]
FileExtensionOverride()80     public void FileExtensionOverride()
81     {
82         var fileProto = CreateFileProto();
83         SetTestFeature(fileProto, 3);
84         SetTestFeature(fileProto.Extension[0], 5);
85         var fileDescriptor = Build(fileProto);
86         Assert.AreEqual(5, GetTestFeature(fileDescriptor.Extensions.UnorderedExtensions[0].Features));
87     }
88 
89     [Test]
FileServiceInherit()90     public void FileServiceInherit()
91     {
92         var fileProto = CreateFileProto();
93         SetTestFeature(fileProto, 3);
94         var fileDescriptor = Build(fileProto);
95         Assert.AreEqual(3, GetTestFeature(fileDescriptor.Services[0].Features));
96     }
97 
98     [Test]
FileServiceOverride()99     public void FileServiceOverride()
100     {
101         var fileProto = CreateFileProto();
102         SetTestFeature(fileProto, 3);
103         SetTestFeature(fileProto.Service[0], 5);
104         var fileDescriptor = Build(fileProto);
105         Assert.AreEqual(5, GetTestFeature(fileDescriptor.Services[0].Features));
106     }
107 
108     [Test]
MessageFieldInherit()109     public void MessageFieldInherit()
110     {
111         var fileProto = CreateFileProto();
112         SetTestFeature(fileProto.MessageType[0], 3);
113         var fileDescriptor = Build(fileProto);
114         Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Fields.InFieldNumberOrder()[0].Features));
115     }
116 
117     [Test]
MessageFieldOverride()118     public void MessageFieldOverride()
119     {
120         var fileProto = CreateFileProto();
121         SetTestFeature(fileProto.MessageType[0], 3);
122         SetTestFeature(fileProto.MessageType[0].Field[0], 5);
123         var fileDescriptor = Build(fileProto);
124         Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Fields.InFieldNumberOrder()[0].Features));
125     }
126 
127     [Test]
MessageEnumInherit()128     public void MessageEnumInherit()
129     {
130         var fileProto = CreateFileProto();
131         SetTestFeature(fileProto.MessageType[0], 3);
132         var fileDescriptor = Build(fileProto);
133         Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].EnumTypes[0].Features));
134     }
135 
136     [Test]
MessageEnumOverride()137     public void MessageEnumOverride()
138     {
139         var fileProto = CreateFileProto();
140         SetTestFeature(fileProto.MessageType[0], 3);
141         SetTestFeature(fileProto.MessageType[0].EnumType[0], 5);
142         var fileDescriptor = Build(fileProto);
143         Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].EnumTypes[0].Features));
144     }
145 
146     [Test]
MessageMessageInherit()147     public void MessageMessageInherit()
148     {
149         var fileProto = CreateFileProto();
150         SetTestFeature(fileProto.MessageType[0], 3);
151         var fileDescriptor = Build(fileProto);
152         Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].NestedTypes[0].Features));
153     }
154 
155     [Test]
MessageMessageOverride()156     public void MessageMessageOverride()
157     {
158         var fileProto = CreateFileProto();
159         SetTestFeature(fileProto.MessageType[0], 3);
160         SetTestFeature(fileProto.MessageType[0].NestedType[0], 5);
161         var fileDescriptor = Build(fileProto);
162         Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].NestedTypes[0].Features));
163     }
164 
165     [Test]
MessageExtensionInherit()166     public void MessageExtensionInherit()
167     {
168         var fileProto = CreateFileProto();
169         SetTestFeature(fileProto.MessageType[0], 3);
170         var fileDescriptor = Build(fileProto);
171         Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Extensions.UnorderedExtensions[0].Features));
172     }
173 
174     [Test]
MessageExtensionOverride()175     public void MessageExtensionOverride()
176     {
177         var fileProto = CreateFileProto();
178         SetTestFeature(fileProto.MessageType[0], 3);
179         SetTestFeature(fileProto.MessageType[0].Extension[0], 5);
180         var fileDescriptor = Build(fileProto);
181         Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Extensions.UnorderedExtensions[0].Features));
182     }
183 
184     [Test]
MessageOneofInherit()185     public void MessageOneofInherit()
186     {
187         var fileProto = CreateFileProto();
188         SetTestFeature(fileProto.MessageType[0], 3);
189         var fileDescriptor = Build(fileProto);
190         Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Features));
191     }
192 
193     [Test]
MessageOneofOverride()194     public void MessageOneofOverride()
195     {
196         var fileProto = CreateFileProto();
197         SetTestFeature(fileProto.MessageType[0], 3);
198         SetTestFeature(fileProto.MessageType[0].OneofDecl[0], 5);
199         var fileDescriptor = Build(fileProto);
200         Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Fields[0].Features));
201     }
202 
203     [Test]
OneofFieldInherit()204     public void OneofFieldInherit()
205     {
206         var fileProto = CreateFileProto();
207         SetTestFeature(fileProto.MessageType[0], 3);
208         var fileDescriptor = Build(fileProto);
209         Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Fields[0].Features));
210     }
211 
212     [Test]
OneofFieldOverride()213     public void OneofFieldOverride()
214     {
215         var fileProto = CreateFileProto();
216         SetTestFeature(fileProto.MessageType[0], 3);
217         SetTestFeature(fileProto.MessageType[0].OneofDecl[0], 5);
218         var fileDescriptor = Build(fileProto);
219         Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Features));
220     }
221 
222     [Test]
EnumValueInherit()223     public void EnumValueInherit()
224     {
225         var fileProto = CreateFileProto();
226         SetTestFeature(fileProto.EnumType[0], 3);
227         var fileDescriptor = Build(fileProto);
228         Assert.AreEqual(3, GetTestFeature(fileDescriptor.EnumTypes[0].Values[0].Features));
229     }
230 
231     [Test]
EnumValueOverride()232     public void EnumValueOverride()
233     {
234         var fileProto = CreateFileProto();
235         SetTestFeature(fileProto.MessageType[0], 3);
236         SetTestFeature(fileProto.EnumType[0].Value[0], 5);
237         var fileDescriptor = Build(fileProto);
238         Assert.AreEqual(5, GetTestFeature(fileDescriptor.EnumTypes[0].Values[0].Features));
239     }
240 
241     [Test]
ServiceMethodInherit()242     public void ServiceMethodInherit()
243     {
244         var fileProto = CreateFileProto();
245         SetTestFeature(fileProto.Service[0], 3);
246         var fileDescriptor = Build(fileProto);
247         Assert.AreEqual(3, GetTestFeature(fileDescriptor.Services[0].Methods[0].Features));
248     }
249 
250     [Test]
ServiceMethodOverride()251     public void ServiceMethodOverride()
252     {
253         var fileProto = CreateFileProto();
254         SetTestFeature(fileProto.Service[0], 3);
255         SetTestFeature(fileProto.Service[0].Method[0], 5);
256         var fileDescriptor = Build(fileProto);
257         Assert.AreEqual(5, GetTestFeature(fileDescriptor.Services[0].Methods[0].Features));
258     }
259 
260     private static int GetTestFeature(FeatureSetDescriptor features) =>
261         (int)(features.Proto.GetExtension(UnittestFeaturesExtensions.Test) ?? new TestFeatures())
262             .MultipleFeature;
263 
SetTestFeature(FileDescriptorProto proto, int value)264     private static void SetTestFeature(FileDescriptorProto proto, int value)
265     {
266         proto.Options ??= new FileOptions();
267         proto.Options.Features ??= new FeatureSet();
268         SetTestFeature(proto.Options.Features, value);
269     }
270 
SetTestFeature(DescriptorProto proto, int value)271     private static void SetTestFeature(DescriptorProto proto, int value)
272     {
273         proto.Options ??= new MessageOptions();
274         proto.Options.Features ??= new FeatureSet();
275         SetTestFeature(proto.Options.Features, value);
276     }
277 
SetTestFeature(EnumDescriptorProto proto, int value)278     private static void SetTestFeature(EnumDescriptorProto proto, int value)
279     {
280         proto.Options ??= new EnumOptions();
281         proto.Options.Features ??= new FeatureSet();
282         SetTestFeature(proto.Options.Features, value);
283     }
284 
SetTestFeature(EnumValueDescriptorProto proto, int value)285     private static void SetTestFeature(EnumValueDescriptorProto proto, int value)
286     {
287         proto.Options ??= new EnumValueOptions();
288         proto.Options.Features ??= new FeatureSet();
289         SetTestFeature(proto.Options.Features, value);
290     }
291 
SetTestFeature(FieldDescriptorProto proto, int value)292     private static void SetTestFeature(FieldDescriptorProto proto, int value)
293     {
294         proto.Options ??= new FieldOptions();
295         proto.Options.Features ??= new FeatureSet();
296         SetTestFeature(proto.Options.Features, value);
297     }
298 
SetTestFeature(ServiceDescriptorProto proto, int value)299     private static void SetTestFeature(ServiceDescriptorProto proto, int value)
300     {
301         proto.Options ??= new ServiceOptions();
302         proto.Options.Features ??= new FeatureSet();
303         SetTestFeature(proto.Options.Features, value);
304     }
305 
SetTestFeature(OneofDescriptorProto proto, int value)306     private static void SetTestFeature(OneofDescriptorProto proto, int value)
307     {
308         proto.Options ??= new OneofOptions();
309         proto.Options.Features ??= new FeatureSet();
310         SetTestFeature(proto.Options.Features, value);
311     }
312 
SetTestFeature(MethodDescriptorProto proto, int value)313     private static void SetTestFeature(MethodDescriptorProto proto, int value)
314     {
315         proto.Options ??= new MethodOptions();
316         proto.Options.Features ??= new FeatureSet();
317         SetTestFeature(proto.Options.Features, value);
318     }
319 
SetTestFeature(FeatureSet features, int value)320     private static void SetTestFeature(FeatureSet features, int value) =>
321         features.SetExtension(UnittestFeaturesExtensions.Test,
322                               new TestFeatures { MultipleFeature = (Pb.EnumFeature)value });
323 
324     private static FileDescriptor Build(FileDescriptorProto fileProto) =>
325         FileDescriptor.BuildFromByteStrings(new[] { fileProto.ToByteString() }, new ExtensionRegistry { UnittestFeaturesExtensions.Test })[0];
326 
CreateFileProto()327     private static FileDescriptorProto CreateFileProto() => new FileDescriptorProto
328     {
329         Name = "some/filename/some.proto",
330         Package = "proto2_unittest",
331         Edition = Edition._2023,
332         Syntax = "editions",
333         Extension =
334         {
335             new FieldDescriptorProto { Name = "top_extension", Number = 10, Type = Type.Int32, Label = Label.Optional, Extendee = ".proto2_unittest.TopMessage" }
336         },
337         EnumType =
338         {
339             new EnumDescriptorProto { Name = "TopEnum", Value = { new EnumValueDescriptorProto { Name = "TOP_VALUE", Number = 0 } } }
340         },
341         MessageType =
342         {
343             new DescriptorProto
344             {
345                 Name = "TopMessage",
346                 Field =
347                 {
348                     new FieldDescriptorProto { Name = "field", Number = 1, Type = Type.Int32, Label = Label.Optional },
349                     new FieldDescriptorProto { Name = "oneof_field", Number = 2, Type = Type.Int32, Label = Label.Optional, OneofIndex = 0 }
350                 },
351                 Extension =
352                 {
353                     new FieldDescriptorProto { Name = "nested_extension", Number = 11, Type = Type.Int32, Label = Label.Optional, Extendee = ".proto2_unittest.TopMessage" }
354                 },
355                 NestedType =
356                 {
357                     new DescriptorProto { Name = "NestedMessage" },
358                 },
359                 EnumType =
360                 {
361                     new EnumDescriptorProto { Name = "NestedEnum", Value = { new EnumValueDescriptorProto { Name = "NESTED_VALUE", Number = 0 } } }
362                 },
363                 OneofDecl = { new OneofDescriptorProto { Name = "Oneof" } }
364             }
365         },
366         Service =
367         {
368             new ServiceDescriptorProto
369             {
370                 Name = "TestService",
371                 Method = { new MethodDescriptorProto { Name = "CallMethod", InputType = ".proto2_unittest.TopMessage", OutputType = ".proto2_unittest.TopMessage" } }
372             }
373         }
374     };
375 }
376