| #region Copyright notice and license | |
| // Protocol Buffers - Google's data interchange format | |
| // Copyright 2008 Google Inc. All rights reserved. | |
| // | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file or at | |
| // https://developers.google.com/open-source/licenses/bsd | |
| #endregion | |
| using Google.Protobuf.Reflection; | |
| using NUnit.Framework; | |
| using Pb; | |
| using static Google.Protobuf.Reflection.FieldDescriptorProto.Types; | |
| using Type = Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type; | |
| namespace Google.Protobuf.Test.Reflection; | |
| public class FeatureInheritanceTest | |
| { | |
| // Note: there's no test for file defaults, as we don't have the same access to modify the | |
| // global defaults in C# that exists in Java. | |
| [Test] | |
| public void FileOverrides() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.Features)); | |
| } | |
| [Test] | |
| public void FileMessageInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Features)); | |
| } | |
| [Test] | |
| public void FileMessageOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| SetTestFeature(fileProto.MessageType[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Features)); | |
| } | |
| [Test] | |
| public void FileEnumInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.EnumTypes[0].Features)); | |
| } | |
| [Test] | |
| public void FileEnumOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| SetTestFeature(fileProto.EnumType[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.EnumTypes[0].Features)); | |
| } | |
| [Test] | |
| public void FileExtensionInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.EnumTypes[0].Features)); | |
| } | |
| [Test] | |
| public void FileExtensionOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| SetTestFeature(fileProto.Extension[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.Extensions.UnorderedExtensions[0].Features)); | |
| } | |
| [Test] | |
| public void FileServiceInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.Services[0].Features)); | |
| } | |
| [Test] | |
| public void FileServiceOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto, 3); | |
| SetTestFeature(fileProto.Service[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.Services[0].Features)); | |
| } | |
| [Test] | |
| public void MessageFieldInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Fields.InFieldNumberOrder()[0].Features)); | |
| } | |
| [Test] | |
| public void MessageFieldOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| SetTestFeature(fileProto.MessageType[0].Field[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Fields.InFieldNumberOrder()[0].Features)); | |
| } | |
| [Test] | |
| public void MessageEnumInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].EnumTypes[0].Features)); | |
| } | |
| [Test] | |
| public void MessageEnumOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| SetTestFeature(fileProto.MessageType[0].EnumType[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].EnumTypes[0].Features)); | |
| } | |
| [Test] | |
| public void MessageMessageInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].NestedTypes[0].Features)); | |
| } | |
| [Test] | |
| public void MessageMessageOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| SetTestFeature(fileProto.MessageType[0].NestedType[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].NestedTypes[0].Features)); | |
| } | |
| [Test] | |
| public void MessageExtensionInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Extensions.UnorderedExtensions[0].Features)); | |
| } | |
| [Test] | |
| public void MessageExtensionOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| SetTestFeature(fileProto.MessageType[0].Extension[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Extensions.UnorderedExtensions[0].Features)); | |
| } | |
| [Test] | |
| public void MessageOneofInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Features)); | |
| } | |
| [Test] | |
| public void MessageOneofOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| SetTestFeature(fileProto.MessageType[0].OneofDecl[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Fields[0].Features)); | |
| } | |
| [Test] | |
| public void OneofFieldInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Fields[0].Features)); | |
| } | |
| [Test] | |
| public void OneofFieldOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| SetTestFeature(fileProto.MessageType[0].OneofDecl[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.MessageTypes[0].Oneofs[0].Features)); | |
| } | |
| [Test] | |
| public void EnumValueInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.EnumType[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.EnumTypes[0].Values[0].Features)); | |
| } | |
| [Test] | |
| public void EnumValueOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.MessageType[0], 3); | |
| SetTestFeature(fileProto.EnumType[0].Value[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.EnumTypes[0].Values[0].Features)); | |
| } | |
| [Test] | |
| public void ServiceMethodInherit() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.Service[0], 3); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(3, GetTestFeature(fileDescriptor.Services[0].Methods[0].Features)); | |
| } | |
| [Test] | |
| public void ServiceMethodOverride() | |
| { | |
| var fileProto = CreateFileProto(); | |
| SetTestFeature(fileProto.Service[0], 3); | |
| SetTestFeature(fileProto.Service[0].Method[0], 5); | |
| var fileDescriptor = Build(fileProto); | |
| Assert.AreEqual(5, GetTestFeature(fileDescriptor.Services[0].Methods[0].Features)); | |
| } | |
| private static int GetTestFeature(FeatureSetDescriptor features) => | |
| (int)(features.Proto.GetExtension(UnittestFeaturesExtensions.Test) ?? new TestFeatures()) | |
| .MultipleFeature; | |
| private static void SetTestFeature(FileDescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new FileOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(DescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new MessageOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(EnumDescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new EnumOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(EnumValueDescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new EnumValueOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(FieldDescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new FieldOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(ServiceDescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new ServiceOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(OneofDescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new OneofOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(MethodDescriptorProto proto, int value) | |
| { | |
| proto.Options ??= new MethodOptions(); | |
| proto.Options.Features ??= new FeatureSet(); | |
| SetTestFeature(proto.Options.Features, value); | |
| } | |
| private static void SetTestFeature(FeatureSet features, int value) => | |
| features.SetExtension(UnittestFeaturesExtensions.Test, | |
| new TestFeatures { MultipleFeature = (Pb.EnumFeature)value }); | |
| private static FileDescriptor Build(FileDescriptorProto fileProto) => | |
| FileDescriptor.BuildFromByteStrings(new[] { fileProto.ToByteString() }, new ExtensionRegistry { UnittestFeaturesExtensions.Test })[0]; | |
| private static FileDescriptorProto CreateFileProto() => new FileDescriptorProto | |
| { | |
| Name = "some/filename/some.proto", | |
| Package = "proto2_unittest", | |
| Edition = Edition._2023, | |
| Syntax = "editions", | |
| Extension = | |
| { | |
| new FieldDescriptorProto { Name = "top_extension", Number = 10, Type = Type.Int32, Label = Label.Optional, Extendee = ".proto2_unittest.TopMessage" } | |
| }, | |
| EnumType = | |
| { | |
| new EnumDescriptorProto { Name = "TopEnum", Value = { new EnumValueDescriptorProto { Name = "TOP_VALUE", Number = 0 } } } | |
| }, | |
| MessageType = | |
| { | |
| new DescriptorProto | |
| { | |
| Name = "TopMessage", | |
| Field = | |
| { | |
| new FieldDescriptorProto { Name = "field", Number = 1, Type = Type.Int32, Label = Label.Optional }, | |
| new FieldDescriptorProto { Name = "oneof_field", Number = 2, Type = Type.Int32, Label = Label.Optional, OneofIndex = 0 } | |
| }, | |
| Extension = | |
| { | |
| new FieldDescriptorProto { Name = "nested_extension", Number = 11, Type = Type.Int32, Label = Label.Optional, Extendee = ".proto2_unittest.TopMessage" } | |
| }, | |
| NestedType = | |
| { | |
| new DescriptorProto { Name = "NestedMessage" }, | |
| }, | |
| EnumType = | |
| { | |
| new EnumDescriptorProto { Name = "NestedEnum", Value = { new EnumValueDescriptorProto { Name = "NESTED_VALUE", Number = 0 } } } | |
| }, | |
| OneofDecl = { new OneofDescriptorProto { Name = "Oneof" } } | |
| } | |
| }, | |
| Service = | |
| { | |
| new ServiceDescriptorProto | |
| { | |
| Name = "TestService", | |
| Method = { new MethodDescriptorProto { Name = "CallMethod", InputType = ".proto2_unittest.TopMessage", OutputType = ".proto2_unittest.TopMessage" } } | |
| } | |
| } | |
| }; | |
| } |