blob: fab983d4635176f85799717a4707c9c1ed79d2ae [file] [log] [blame]
Jon Skeet9f37de92015-07-14 10:24:52 +01001#region Copyright notice and license
2// Protocol Buffers - Google's data interchange format
3// Copyright 2008 Google Inc. All rights reserved.
4// https://developers.google.com/protocol-buffers/
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31#endregion
32
Jon Skeet9f37de92015-07-14 10:24:52 +010033using Google.Protobuf.TestProtos;
34using NUnit.Framework;
Jon Skeet97737072020-04-17 08:36:46 +010035using ProtobufUnittest;
Jon Skeet228530e2018-08-08 19:51:16 -070036using System;
37using System.Collections.Generic;
Jon Skeetf01d9e52021-01-20 08:11:27 +000038using System.IO;
Jon Skeet228530e2018-08-08 19:51:16 -070039using System.Linq;
Jon Skeetf01d9e52021-01-20 08:11:27 +000040using UnitTest.Issues.TestProtos;
Jon Skeet9f37de92015-07-14 10:24:52 +010041
42namespace Google.Protobuf.Reflection
43{
44 /// <summary>
45 /// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
46 /// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
47 /// </summary>
48 public class DescriptorsTest
49 {
50 [Test]
Jon Skeet228530e2018-08-08 19:51:16 -070051 public void FileDescriptor_GeneratedCode()
Jon Skeet9f37de92015-07-14 10:24:52 +010052 {
Jon Skeet228530e2018-08-08 19:51:16 -070053 TestFileDescriptor(
54 UnittestProto3Reflection.Descriptor,
55 UnittestImportProto3Reflection.Descriptor,
56 UnittestImportPublicProto3Reflection.Descriptor);
57 }
58
59 [Test]
60 public void FileDescriptor_BuildFromByteStrings()
61 {
62 // The descriptors have to be supplied in an order such that all the
63 // dependencies come before the descriptors depending on them.
64 var descriptorData = new List<ByteString>
65 {
Jon Skeet1376ee42018-09-18 07:33:39 +010066 UnittestImportPublicProto3Reflection.Descriptor.SerializedData,
67 UnittestImportProto3Reflection.Descriptor.SerializedData,
68 UnittestProto3Reflection.Descriptor.SerializedData
Jon Skeet228530e2018-08-08 19:51:16 -070069 };
70 var converted = FileDescriptor.BuildFromByteStrings(descriptorData);
71 Assert.AreEqual(3, converted.Count);
72 TestFileDescriptor(converted[2], converted[1], converted[0]);
73 }
74
Jon Skeetf01d9e52021-01-20 08:11:27 +000075 [Test]
76 public void FileDescriptor_BuildFromByteStrings_WithExtensionRegistry()
77 {
78 var extension = UnittestCustomOptionsProto3Extensions.MessageOpt1;
79
80 var byteStrings = new[]
81 {
82 DescriptorReflection.Descriptor.Proto.ToByteString(),
83 UnittestCustomOptionsProto3Reflection.Descriptor.Proto.ToByteString()
84 };
85 var registry = new ExtensionRegistry { extension };
86
87 var descriptor = FileDescriptor.BuildFromByteStrings(byteStrings, registry).Last();
88 var message = descriptor.MessageTypes.Single(t => t.Name == nameof(TestMessageWithCustomOptions));
89 var extensionValue = message.GetOptions().GetExtension(extension);
90 Assert.AreEqual(-56, extensionValue);
91 }
92
Jon Skeet228530e2018-08-08 19:51:16 -070093 private void TestFileDescriptor(FileDescriptor file, FileDescriptor importedFile, FileDescriptor importedPublicFile)
94 {
Jon Skeet8cf53f82017-11-10 09:50:47 +000095 Assert.AreEqual("unittest_proto3.proto", file.Name);
96 Assert.AreEqual("protobuf_unittest3", file.Package);
Jon Skeet9f37de92015-07-14 10:24:52 +010097
98 Assert.AreEqual("UnittestProto", file.Proto.Options.JavaOuterClassname);
Jon Skeet8cf53f82017-11-10 09:50:47 +000099 Assert.AreEqual("unittest_proto3.proto", file.Proto.Name);
Jon Skeet9f37de92015-07-14 10:24:52 +0100100
Jon Skeet8cf53f82017-11-10 09:50:47 +0000101 // unittest_proto3.proto doesn't have any public imports, but unittest_import_proto3.proto does.
Jon Skeet9f37de92015-07-14 10:24:52 +0100102 Assert.AreEqual(0, file.PublicDependencies.Count);
Jon Skeet228530e2018-08-08 19:51:16 -0700103 Assert.AreEqual(1, importedFile.PublicDependencies.Count);
104 Assert.AreEqual(importedPublicFile, importedFile.PublicDependencies[0]);
Jon Skeet9f37de92015-07-14 10:24:52 +0100105
106 Assert.AreEqual(1, file.Dependencies.Count);
Jon Skeet228530e2018-08-08 19:51:16 -0700107 Assert.AreEqual(importedFile, file.Dependencies[0]);
Jon Skeet9f37de92015-07-14 10:24:52 +0100108
Jon Skeet9f37de92015-07-14 10:24:52 +0100109 Assert.Null(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
Jon Skeet8cf53f82017-11-10 09:50:47 +0000110 Assert.Null(file.FindTypeByName<MessageDescriptor>("protobuf_unittest3.TestAllTypes"));
Jon Skeet9f37de92015-07-14 10:24:52 +0100111 for (int i = 0; i < file.MessageTypes.Count; i++)
112 {
113 Assert.AreEqual(i, file.MessageTypes[i].Index);
114 }
115
116 Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
117 Assert.Null(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
Jon Skeet8cf53f82017-11-10 09:50:47 +0000118 Assert.Null(file.FindTypeByName<EnumDescriptor>("protobuf_unittest3.ForeignEnum"));
Jon Skeet228530e2018-08-08 19:51:16 -0700119 Assert.AreEqual(1, importedFile.EnumTypes.Count);
120 Assert.AreEqual("ImportEnum", importedFile.EnumTypes[0].Name);
Jon Skeet9f37de92015-07-14 10:24:52 +0100121 for (int i = 0; i < file.EnumTypes.Count; i++)
122 {
123 Assert.AreEqual(i, file.EnumTypes[i].Index);
124 }
Jan Tattermusch3b8c83e2015-07-24 20:27:35 -0700125
126 Assert.AreEqual(10, file.SerializedData[0]);
Jon Skeet9f37de92015-07-14 10:24:52 +0100127 }
128
129 [Test]
Jon Skeet8cf53f82017-11-10 09:50:47 +0000130 public void FileDescriptor_NonRootPath()
131 {
132 // unittest_proto3.proto used to be in google/protobuf. Now it's in the C#-specific location,
133 // let's test something that's still in a directory.
134 FileDescriptor file = UnittestWellKnownTypesReflection.Descriptor;
135 Assert.AreEqual("google/protobuf/unittest_well_known_types.proto", file.Name);
136 Assert.AreEqual("protobuf_unittest", file.Package);
137 }
138
139 [Test]
Jon Skeet228530e2018-08-08 19:51:16 -0700140 public void FileDescriptor_BuildFromByteStrings_MissingDependency()
141 {
142 var descriptorData = new List<ByteString>
143 {
Jon Skeet1376ee42018-09-18 07:33:39 +0100144 UnittestImportProto3Reflection.Descriptor.SerializedData,
145 UnittestProto3Reflection.Descriptor.SerializedData,
Jon Skeet228530e2018-08-08 19:51:16 -0700146 };
147 // This will fail, because we're missing UnittestImportPublicProto3Reflection
148 Assert.Throws<ArgumentException>(() => FileDescriptor.BuildFromByteStrings(descriptorData));
149 }
150
151 [Test]
152 public void FileDescriptor_BuildFromByteStrings_DuplicateNames()
153 {
154 var descriptorData = new List<ByteString>
155 {
Jon Skeet1376ee42018-09-18 07:33:39 +0100156 UnittestImportPublicProto3Reflection.Descriptor.SerializedData,
157 UnittestImportPublicProto3Reflection.Descriptor.SerializedData,
Jon Skeet228530e2018-08-08 19:51:16 -0700158 };
159 // This will fail due to the same name being used twice
160 Assert.Throws<ArgumentException>(() => FileDescriptor.BuildFromByteStrings(descriptorData));
161 }
162
163 [Test]
164 public void FileDescriptor_BuildFromByteStrings_IncorrectOrder()
165 {
166 var descriptorData = new List<ByteString>
167 {
Jon Skeet1376ee42018-09-18 07:33:39 +0100168 UnittestProto3Reflection.Descriptor.SerializedData,
169 UnittestImportPublicProto3Reflection.Descriptor.SerializedData,
170 UnittestImportProto3Reflection.Descriptor.SerializedData
Jon Skeet228530e2018-08-08 19:51:16 -0700171 };
172 // This will fail, because the dependencies should come first
173 Assert.Throws<ArgumentException>(() => FileDescriptor.BuildFromByteStrings(descriptorData));
174
175 }
176
177 [Test]
178 public void MessageDescriptorFromGeneratedCodeFileDescriptor()
179 {
180 var file = UnittestProto3Reflection.Descriptor;
181
182 MessageDescriptor messageType = TestAllTypes.Descriptor;
183 Assert.AreSame(typeof(TestAllTypes), messageType.ClrType);
184 Assert.AreSame(TestAllTypes.Parser, messageType.Parser);
185 Assert.AreEqual(messageType, file.MessageTypes[0]);
186 Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
187 }
188
189 [Test]
Jon Skeet9f37de92015-07-14 10:24:52 +0100190 public void MessageDescriptor()
191 {
192 MessageDescriptor messageType = TestAllTypes.Descriptor;
193 MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor;
194
195 Assert.AreEqual("TestAllTypes", messageType.Name);
Jon Skeet8cf53f82017-11-10 09:50:47 +0000196 Assert.AreEqual("protobuf_unittest3.TestAllTypes", messageType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +0000197 Assert.AreEqual(UnittestProto3Reflection.Descriptor, messageType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100198 Assert.IsNull(messageType.ContainingType);
199 Assert.IsNull(messageType.Proto.Options);
200
201 Assert.AreEqual("TestAllTypes", messageType.Name);
202
203 Assert.AreEqual("NestedMessage", nestedType.Name);
Jon Skeet8cf53f82017-11-10 09:50:47 +0000204 Assert.AreEqual("protobuf_unittest3.TestAllTypes.NestedMessage", nestedType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +0000205 Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100206 Assert.AreEqual(messageType, nestedType.ContainingType);
207
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100208 FieldDescriptor field = messageType.Fields.InDeclarationOrder()[0];
Jon Skeet9f37de92015-07-14 10:24:52 +0100209 Assert.AreEqual("single_int32", field.Name);
210 Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("single_int32"));
211 Assert.Null(messageType.FindDescriptor<FieldDescriptor>("no_such_field"));
212 Assert.AreEqual(field, messageType.FindFieldByNumber(1));
213 Assert.Null(messageType.FindFieldByNumber(571283));
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100214 var fieldsInDeclarationOrder = messageType.Fields.InDeclarationOrder();
215 for (int i = 0; i < fieldsInDeclarationOrder.Count; i++)
Jon Skeet9f37de92015-07-14 10:24:52 +0100216 {
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100217 Assert.AreEqual(i, fieldsInDeclarationOrder[i].Index);
Jon Skeet9f37de92015-07-14 10:24:52 +0100218 }
219
220 Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
221 Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage"));
222 Assert.Null(messageType.FindDescriptor<MessageDescriptor>("NoSuchType"));
223 for (int i = 0; i < messageType.NestedTypes.Count; i++)
224 {
225 Assert.AreEqual(i, messageType.NestedTypes[i].Index);
226 }
227
228 Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum"));
229 Assert.Null(messageType.FindDescriptor<EnumDescriptor>("NoSuchType"));
230 for (int i = 0; i < messageType.EnumTypes.Count; i++)
231 {
232 Assert.AreEqual(i, messageType.EnumTypes[i].Index);
233 }
234 }
235
236 [Test]
Jon Skeetbaa4a212018-08-29 10:32:42 +0100237 public void FieldDescriptor_GeneratedCode()
Jon Skeet9f37de92015-07-14 10:24:52 +0100238 {
Jon Skeetbaa4a212018-08-29 10:32:42 +0100239 TestFieldDescriptor(UnittestProto3Reflection.Descriptor, TestAllTypes.Descriptor, ForeignMessage.Descriptor, ImportMessage.Descriptor);
240 }
241
242 [Test]
243 public void FieldDescriptor_BuildFromByteStrings()
244 {
245 // The descriptors have to be supplied in an order such that all the
246 // dependencies come before the descriptors depending on them.
247 var descriptorData = new List<ByteString>
248 {
Jon Skeet1376ee42018-09-18 07:33:39 +0100249 UnittestImportPublicProto3Reflection.Descriptor.SerializedData,
250 UnittestImportProto3Reflection.Descriptor.SerializedData,
251 UnittestProto3Reflection.Descriptor.SerializedData
Jon Skeetbaa4a212018-08-29 10:32:42 +0100252 };
253 var converted = FileDescriptor.BuildFromByteStrings(descriptorData);
254 TestFieldDescriptor(
255 converted[2],
256 converted[2].FindTypeByName<MessageDescriptor>("TestAllTypes"),
257 converted[2].FindTypeByName<MessageDescriptor>("ForeignMessage"),
258 converted[1].FindTypeByName<MessageDescriptor>("ImportMessage"));
259 }
260
261 public void TestFieldDescriptor(
262 FileDescriptor unitTestProto3Descriptor,
263 MessageDescriptor testAllTypesDescriptor,
264 MessageDescriptor foreignMessageDescriptor,
265 MessageDescriptor importMessageDescriptor)
266 {
267 FieldDescriptor primitiveField = testAllTypesDescriptor.FindDescriptor<FieldDescriptor>("single_int32");
268 FieldDescriptor enumField = testAllTypesDescriptor.FindDescriptor<FieldDescriptor>("single_nested_enum");
269 FieldDescriptor foreignMessageField = testAllTypesDescriptor.FindDescriptor<FieldDescriptor>("single_foreign_message");
270 FieldDescriptor importMessageField = testAllTypesDescriptor.FindDescriptor<FieldDescriptor>("single_import_message");
Jon Skeet97737072020-04-17 08:36:46 +0100271 FieldDescriptor fieldInOneof = testAllTypesDescriptor.FindDescriptor<FieldDescriptor>("oneof_string");
Jon Skeet9f37de92015-07-14 10:24:52 +0100272
273 Assert.AreEqual("single_int32", primitiveField.Name);
Jon Skeet8cf53f82017-11-10 09:50:47 +0000274 Assert.AreEqual("protobuf_unittest3.TestAllTypes.single_int32",
Jon Skeet9f37de92015-07-14 10:24:52 +0100275 primitiveField.FullName);
276 Assert.AreEqual(1, primitiveField.FieldNumber);
Jon Skeetbaa4a212018-08-29 10:32:42 +0100277 Assert.AreEqual(testAllTypesDescriptor, primitiveField.ContainingType);
278 Assert.AreEqual(unitTestProto3Descriptor, primitiveField.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100279 Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
280 Assert.IsNull(primitiveField.Proto.Options);
Xiang Daie4794102019-02-21 11:28:50 +0800281
Jon Skeet9f37de92015-07-14 10:24:52 +0100282 Assert.AreEqual("single_nested_enum", enumField.Name);
283 Assert.AreEqual(FieldType.Enum, enumField.FieldType);
Jon Skeetbaa4a212018-08-29 10:32:42 +0100284 Assert.AreEqual(testAllTypesDescriptor.EnumTypes[0], enumField.EnumType);
Jon Skeet9f37de92015-07-14 10:24:52 +0100285
Jon Skeetbaa4a212018-08-29 10:32:42 +0100286 Assert.AreEqual("single_foreign_message", foreignMessageField.Name);
287 Assert.AreEqual(FieldType.Message, foreignMessageField.FieldType);
288 Assert.AreEqual(foreignMessageDescriptor, foreignMessageField.MessageType);
289
290 Assert.AreEqual("single_import_message", importMessageField.Name);
291 Assert.AreEqual(FieldType.Message, importMessageField.FieldType);
292 Assert.AreEqual(importMessageDescriptor, importMessageField.MessageType);
Jon Skeet97737072020-04-17 08:36:46 +0100293
294 // For a field in a regular onoef, ContainingOneof and RealContainingOneof should be the same.
295 Assert.AreEqual("oneof_field", fieldInOneof.ContainingOneof.Name);
296 Assert.AreSame(fieldInOneof.ContainingOneof, fieldInOneof.RealContainingOneof);
Jon Skeet9f37de92015-07-14 10:24:52 +0100297 }
298
299 [Test]
300 public void FieldDescriptorLabel()
301 {
302 FieldDescriptor singleField =
303 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("single_int32");
304 FieldDescriptor repeatedField =
305 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
306
307 Assert.IsFalse(singleField.IsRepeated);
308 Assert.IsTrue(repeatedField.IsRepeated);
309 }
310
311 [Test]
312 public void EnumDescriptor()
313 {
314 // Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
Jon Skeet284bb452015-11-05 09:13:53 +0000315 EnumDescriptor enumType = UnittestProto3Reflection.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
Jon Skeet9f37de92015-07-14 10:24:52 +0100316 EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
317
318 Assert.AreEqual("ForeignEnum", enumType.Name);
Jon Skeet8cf53f82017-11-10 09:50:47 +0000319 Assert.AreEqual("protobuf_unittest3.ForeignEnum", enumType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +0000320 Assert.AreEqual(UnittestProto3Reflection.Descriptor, enumType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100321 Assert.Null(enumType.ContainingType);
322 Assert.Null(enumType.Proto.Options);
323
324 Assert.AreEqual("NestedEnum", nestedType.Name);
Jon Skeet8cf53f82017-11-10 09:50:47 +0000325 Assert.AreEqual("protobuf_unittest3.TestAllTypes.NestedEnum",
Jon Skeet9f37de92015-07-14 10:24:52 +0100326 nestedType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +0000327 Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100328 Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
329
330 EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
331 Assert.AreEqual(value, enumType.Values[1]);
332 Assert.AreEqual("FOREIGN_FOO", value.Name);
333 Assert.AreEqual(4, value.Number);
Jon Skeet84ea2c72016-04-08 12:33:09 +0100334 Assert.AreEqual((int) ForeignEnum.ForeignFoo, value.Number);
Jon Skeet9f37de92015-07-14 10:24:52 +0100335 Assert.AreEqual(value, enumType.FindValueByNumber(4));
336 Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE"));
337 for (int i = 0; i < enumType.Values.Count; i++)
338 {
339 Assert.AreEqual(i, enumType.Values[i].Index);
340 }
341 }
342
343 [Test]
344 public void OneofDescriptor()
345 {
346 OneofDescriptor descriptor = TestAllTypes.Descriptor.FindDescriptor<OneofDescriptor>("oneof_field");
Jon Skeet97737072020-04-17 08:36:46 +0100347 Assert.IsFalse(descriptor.IsSynthetic);
Jon Skeet9f37de92015-07-14 10:24:52 +0100348 Assert.AreEqual("oneof_field", descriptor.Name);
Jon Skeet8cf53f82017-11-10 09:50:47 +0000349 Assert.AreEqual("protobuf_unittest3.TestAllTypes.oneof_field", descriptor.FullName);
Jon Skeet9f37de92015-07-14 10:24:52 +0100350
351 var expectedFields = new[] {
352 TestAllTypes.OneofBytesFieldNumber,
353 TestAllTypes.OneofNestedMessageFieldNumber,
354 TestAllTypes.OneofStringFieldNumber,
355 TestAllTypes.OneofUint32FieldNumber }
356 .Select(fieldNumber => TestAllTypes.Descriptor.FindFieldByNumber(fieldNumber))
357 .ToList();
358 foreach (var field in expectedFields)
359 {
360 Assert.AreSame(descriptor, field.ContainingOneof);
361 }
362
363 CollectionAssert.AreEquivalent(expectedFields, descriptor.Fields);
364 }
Jon Skeet20bf6a52015-07-22 15:14:38 +0100365
366 [Test]
Jon Skeet72ec3362015-11-19 17:13:38 +0000367 public void MapEntryMessageDescriptor()
Jon Skeet20bf6a52015-07-22 15:14:38 +0100368 {
Jon Skeet72ec3362015-11-19 17:13:38 +0000369 var descriptor = MapWellKnownTypes.Descriptor.NestedTypes[0];
370 Assert.IsNull(descriptor.Parser);
371 Assert.IsNull(descriptor.ClrType);
372 Assert.IsNull(descriptor.Fields[1].Accessor);
Jon Skeet20bf6a52015-07-22 15:14:38 +0100373 }
Jon Skeetfd02e452015-07-31 10:32:04 +0100374
375 // From TestFieldOrdering:
376 // string my_string = 11;
377 // int64 my_int = 1;
378 // float my_float = 101;
379 // NestedMessage single_nested_message = 200;
380 [Test]
381 public void FieldListOrderings()
Xiang Daie4794102019-02-21 11:28:50 +0800382 {
Jon Skeetfd02e452015-07-31 10:32:04 +0100383 var fields = TestFieldOrderings.Descriptor.Fields;
384 Assert.AreEqual(new[] { 11, 1, 101, 200 }, fields.InDeclarationOrder().Select(x => x.FieldNumber));
385 Assert.AreEqual(new[] { 1, 11, 101, 200 }, fields.InFieldNumberOrder().Select(x => x.FieldNumber));
386 }
Jan Tattermusch143688f2015-08-14 13:23:44 -0700387
388
389 [Test]
390 public void DescriptorProtoFileDescriptor()
391 {
392 var descriptor = Google.Protobuf.Reflection.FileDescriptor.DescriptorProtoFileDescriptor;
Jon Skeet284bb452015-11-05 09:13:53 +0000393 Assert.AreEqual("google/protobuf/descriptor.proto", descriptor.Name);
Jan Tattermusch143688f2015-08-14 13:23:44 -0700394 }
Jon Skeet7581fd52019-10-30 09:46:24 +0000395
396 [Test]
397 public void DescriptorImportingExtensionsFromOldCodeGen()
398 {
399 // The extension collection includes a null extension. There's not a lot we can do about that
400 // in itself, as the old generator didn't provide us the extension information.
401 var extensions = TestProtos.OldGenerator.OldExtensions2Reflection.Descriptor.Extensions;
402 Assert.AreEqual(1, extensions.UnorderedExtensions.Count);
403 // Note: this assertion is present so that it will fail if OldExtensions2 is regenerated
404 // with a new generator.
405 Assert.Null(extensions.UnorderedExtensions[0].Extension);
406
407 // ... but we can make sure we at least don't cause a failure when retrieving descriptors.
408 // In particular, old_extensions1.proto imports old_extensions2.proto, and this used to cause
409 // an execution-time failure.
410 var importingDescriptor = TestProtos.OldGenerator.OldExtensions1Reflection.Descriptor;
411 Assert.NotNull(importingDescriptor);
412 }
Jon Skeet97737072020-04-17 08:36:46 +0100413
414 [Test]
415 public void Proto3OptionalDescriptors()
416 {
417 var descriptor = TestProto3Optional.Descriptor;
418 var field = descriptor.Fields[TestProto3Optional.OptionalInt32FieldNumber];
419 Assert.NotNull(field.ContainingOneof);
420 Assert.IsTrue(field.ContainingOneof.IsSynthetic);
421 Assert.Null(field.RealContainingOneof);
422 }
423
424
425 [Test]
426 public void SyntheticOneofReflection()
427 {
428 // Expect every oneof in TestProto3Optional to be synthetic
429 var proto3OptionalDescriptor = TestProto3Optional.Descriptor;
430 Assert.AreEqual(0, proto3OptionalDescriptor.RealOneofCount);
431 foreach (var oneof in proto3OptionalDescriptor.Oneofs)
432 {
433 Assert.True(oneof.IsSynthetic);
434 }
435
436 // Expect no oneof in the original proto3 unit test file to be synthetic.
437 foreach (var descriptor in ProtobufTestMessages.Proto3.TestMessagesProto3Reflection.Descriptor.MessageTypes)
438 {
439 Assert.AreEqual(descriptor.Oneofs.Count, descriptor.RealOneofCount);
440 foreach (var oneof in descriptor.Oneofs)
441 {
442 Assert.False(oneof.IsSynthetic);
443 }
444 }
445
446 // Expect no oneof in the original proto2 unit test file to be synthetic.
447 foreach (var descriptor in ProtobufTestMessages.Proto2.TestMessagesProto2Reflection.Descriptor.MessageTypes)
448 {
449 Assert.AreEqual(descriptor.Oneofs.Count, descriptor.RealOneofCount);
450 foreach (var oneof in descriptor.Oneofs)
451 {
452 Assert.False(oneof.IsSynthetic);
453 }
454 }
455 }
Jon Skeet9f37de92015-07-14 10:24:52 +0100456 }
Jon Skeet5e0cfc92015-07-22 18:43:15 +0100457}