blob: 79dbb64531c884c6a49553d897ee8a2679d48ca5 [file] [log] [blame]
#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" } }
}
}
};
}