Merge pull request #990 from jskeet/naming
Tidying up reflection further
This commit is contained in:
commit
41824d93e5
29 changed files with 207 additions and 244 deletions
csharp/src
AddressBook
Google.Protobuf.Conformance
Google.Protobuf.Test
Reflection
TestProtos
Google.Protobuf
src/google/protobuf/compiler/csharp
|
@ -32,7 +32,7 @@ namespace Google.Protobuf.Examples.AddressBook {
|
|||
"GAEgAygLMhAudHV0b3JpYWwuUGVyc29uQlAKFGNvbS5leGFtcGxlLnR1dG9y",
|
||||
"aWFsQhFBZGRyZXNzQm9va1Byb3Rvc6oCJEdvb2dsZS5Qcm90b2J1Zi5FeGFt",
|
||||
"cGxlcy5BZGRyZXNzQm9va2IGcHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person), global::Google.Protobuf.Examples.AddressBook.Person.Parser, new[]{ "Name", "Id", "Email", "Phones" }, null, new[]{ typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber), global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser, new[]{ "Number", "Type" }, null, null, null)}),
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace Conformance {
|
|||
"QlVGEAESCAoESlNPThACKkAKC0ZvcmVpZ25FbnVtEg8KC0ZPUkVJR05fRk9P",
|
||||
"EAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhACQiEKH2NvbS5n",
|
||||
"b29nbGUucHJvdG9idWYuY29uZm9ybWFuY2ViBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.ForeignEnum), }, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat" }, new[]{ "Payload" }, null, null),
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Google.Protobuf.Reflection
|
|||
Assert.AreEqual(UnittestImportProto3Reflection.Descriptor, file.Dependencies[0]);
|
||||
|
||||
MessageDescriptor messageType = TestAllTypes.Descriptor;
|
||||
Assert.AreSame(typeof(TestAllTypes), messageType.GeneratedType);
|
||||
Assert.AreSame(typeof(TestAllTypes), messageType.ClrType);
|
||||
Assert.AreSame(TestAllTypes.Parser, messageType.Parser);
|
||||
Assert.AreEqual(messageType, file.MessageTypes[0]);
|
||||
Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
|
||||
|
@ -227,18 +227,12 @@ namespace Google.Protobuf.Reflection
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void ConstructionWithoutGeneratedCodeInfo()
|
||||
public void MapEntryMessageDescriptor()
|
||||
{
|
||||
var data = UnittestIssuesReflection.Descriptor.Proto.ToByteArray();
|
||||
var newDescriptor = Google.Protobuf.Reflection.FileDescriptor.InternalBuildGeneratedFileFrom(data, new Reflection.FileDescriptor[] { }, null);
|
||||
|
||||
// We should still be able to get at a field...
|
||||
var messageDescriptor = newDescriptor.FindTypeByName<MessageDescriptor>("ItemField");
|
||||
var fieldDescriptor = messageDescriptor.FindFieldByName("item");
|
||||
// But there shouldn't be an accessor (or a generated type for the message, or parser)
|
||||
Assert.IsNull(fieldDescriptor.Accessor);
|
||||
Assert.IsNull(messageDescriptor.GeneratedType);
|
||||
Assert.IsNull(messageDescriptor.Parser);
|
||||
var descriptor = MapWellKnownTypes.Descriptor.NestedTypes[0];
|
||||
Assert.IsNull(descriptor.Parser);
|
||||
Assert.IsNull(descriptor.ClrType);
|
||||
Assert.IsNull(descriptor.Fields[1].Accessor);
|
||||
}
|
||||
|
||||
// From TestFieldOrdering:
|
||||
|
|
|
@ -147,7 +147,7 @@ namespace Google.Protobuf.TestProtos {
|
|||
"dmFsdWUYAiABKAU6AjgBKj8KB01hcEVudW0SEAoMTUFQX0VOVU1fRk9PEAAS",
|
||||
"EAoMTUFQX0VOVU1fQkFSEAESEAoMTUFQX0VOVU1fQkFaEAJCIPgBAaoCGkdv",
|
||||
"b2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zYgZwcm90bzM="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor, },
|
||||
new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.MapEnum), }, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMap), global::Google.Protobuf.TestProtos.TestMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapInt32Bytes", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Google.Protobuf.TestProtos {
|
|||
"UhAIEg4KCklNUE9SVF9CQVoQCUI8Chhjb20uZ29vZ2xlLnByb3RvYnVmLnRl",
|
||||
"c3RIAfgBAaoCGkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zUABiBnByb3Rv",
|
||||
"Mw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportPublicProto3Reflection.Descriptor, },
|
||||
new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), global::Google.Protobuf.TestProtos.ImportMessage.Parser, new[]{ "D" }, null, null, null)
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Google.Protobuf.TestProtos {
|
|||
"bzMucHJvdG8SGHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydCIgChNQdWJsaWNJ",
|
||||
"bXBvcnRNZXNzYWdlEgkKAWUYASABKAVCNwoYY29tLmdvb2dsZS5wcm90b2J1",
|
||||
"Zi50ZXN0qgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), global::Google.Protobuf.TestProtos.PublicImportMessage.Parser, new[]{ "E" }, null, null, null)
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace UnitTest.Issues.TestProtos {
|
|||
"aXZlQmVsb3cQ+///////////ARIVCghNaW51c09uZRD///////////8BKi4K",
|
||||
"DkRlcHJlY2F0ZWRFbnVtEhMKD0RFUFJFQ0FURURfWkVSTxAAEgcKA29uZRAB",
|
||||
"Qh9IAaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZwcm90bzM="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null)})}),
|
||||
|
|
|
@ -150,7 +150,7 @@ namespace Google.Protobuf.TestProtos {
|
|||
"HS5wcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1ZXN0Gh4ucHJvdG9idWZfdW5p",
|
||||
"dHRlc3QuQmFyUmVzcG9uc2VCOkINVW5pdHRlc3RQcm90b0gBgAEBiAEBkAEB",
|
||||
"+AEBqgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportProto3Reflection.Descriptor, },
|
||||
new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ForeignEnum), typeof(global::Google.Protobuf.TestProtos.TestEnumWithDupValue), typeof(global::Google.Protobuf.TestProtos.TestSparseEnum), }, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes), global::Google.Protobuf.TestProtos.TestAllTypes.Parser, new[]{ "SingleInt32", "SingleInt64", "SingleUint32", "SingleUint64", "SingleSint32", "SingleSint64", "SingleFixed32", "SingleFixed64", "SingleSfixed32", "SingleSfixed64", "SingleFloat", "SingleDouble", "SingleBool", "SingleString", "SingleBytes", "SingleNestedMessage", "SingleForeignMessage", "SingleImportMessage", "SingleNestedEnum", "SingleForeignEnum", "SingleImportEnum", "SinglePublicImportMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedPublicImportMessage", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser, new[]{ "Bb" }, null, null, null)}),
|
||||
|
|
|
@ -159,7 +159,7 @@ namespace Google.Protobuf.TestProtos {
|
|||
"AiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZToCOAFCOQoYY29t",
|
||||
"Lmdvb2dsZS5wcm90b2J1Zi50ZXN0UAGqAhpHb29nbGUuUHJvdG9idWYuVGVz",
|
||||
"dFByb3Rvc2IGcHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestWellKnownTypes), global::Google.Protobuf.TestProtos.TestWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null),
|
||||
|
|
|
@ -388,8 +388,7 @@ namespace Google.Protobuf
|
|||
// If it's the message form, we can extract the value first, which *will* be the (possibly boxed) native value,
|
||||
// and then proceed, writing it as if we were definitely in a field. (We never need to wrap it in an extra string...
|
||||
// WriteValue will do the right thing.)
|
||||
// TODO: Detect this differently when we have dynamic messages.
|
||||
if (descriptor.File == Int32Value.Descriptor.File)
|
||||
if (descriptor.IsWrapperType)
|
||||
{
|
||||
if (value is IMessage)
|
||||
{
|
||||
|
|
|
@ -291,8 +291,7 @@ namespace Google.Protobuf
|
|||
{
|
||||
// Parse wrapper types as their constituent types.
|
||||
// TODO: What does this mean for null?
|
||||
// TODO: Detect this differently when we have dynamic messages, and put it in one place...
|
||||
if (field.MessageType.IsWellKnownType && field.MessageType.File == Int32Value.Descriptor.File)
|
||||
if (field.MessageType.IsWrapperType)
|
||||
{
|
||||
field = field.MessageType.Fields[WrappersReflection.WrapperValueFieldNumber];
|
||||
fieldType = field.FieldType;
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace Google.Protobuf.Reflection {
|
|||
"X2NvbW1lbnRzGAYgAygJQlgKE2NvbS5nb29nbGUucHJvdG9idWZCEERlc2Ny",
|
||||
"aXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqICA0dQQqoCGkdvb2dsZS5Qcm90",
|
||||
"b2J1Zi5SZWZsZWN0aW9u"));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null),
|
||||
|
|
|
@ -43,13 +43,13 @@ namespace Google.Protobuf.Reflection
|
|||
private readonly EnumDescriptorProto proto;
|
||||
private readonly MessageDescriptor containingType;
|
||||
private readonly IList<EnumValueDescriptor> values;
|
||||
private readonly Type generatedType;
|
||||
private readonly Type clrType;
|
||||
|
||||
internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, Type generatedType)
|
||||
internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, Type clrType)
|
||||
: base(file, file.ComputeFullName(parent, proto.Name), index)
|
||||
{
|
||||
this.proto = proto;
|
||||
this.generatedType = generatedType;
|
||||
this.clrType = clrType;
|
||||
containingType = parent;
|
||||
|
||||
if (proto.Value.Count == 0)
|
||||
|
@ -73,9 +73,9 @@ namespace Google.Protobuf.Reflection
|
|||
public override string Name { get { return proto.Name; } }
|
||||
|
||||
/// <summary>
|
||||
/// The generated type for this enum, or <c>null</c> if the descriptor does not represent a generated type.
|
||||
/// The CLR type for this enum. For generated code, this will be a CLR enum type.
|
||||
/// </summary>
|
||||
public Type GeneratedType { get { return generatedType; } }
|
||||
public Type ClrType { get { return clrType; } }
|
||||
|
||||
/// <value>
|
||||
/// If this is a nested type, get the outer descriptor, otherwise null.
|
||||
|
|
|
@ -62,8 +62,7 @@ namespace Google.Protobuf.Reflection
|
|||
|
||||
if (FieldNumber <= 0)
|
||||
{
|
||||
throw new DescriptorValidationException(this,
|
||||
"Field numbers must be positive integers.");
|
||||
throw new DescriptorValidationException(this, "Field numbers must be positive integers.");
|
||||
}
|
||||
containingType = parent;
|
||||
// OneofIndex "defaults" to -1 due to a hack in FieldDescriptor.OnConstruction.
|
||||
|
@ -72,7 +71,7 @@ namespace Google.Protobuf.Reflection
|
|||
if (proto.OneofIndex < 0 || proto.OneofIndex >= parent.Proto.OneofDecl.Count)
|
||||
{
|
||||
throw new DescriptorValidationException(this,
|
||||
"FieldDescriptorProto.oneof_index is out of range for type " + parent.Name);
|
||||
$"FieldDescriptorProto.oneof_index is out of range for type {parent.Name}");
|
||||
}
|
||||
containingOneof = parent.Oneofs[proto.OneofIndex];
|
||||
}
|
||||
|
@ -94,13 +93,22 @@ namespace Google.Protobuf.Reflection
|
|||
internal FieldDescriptorProto Proto { get { return proto; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the accessor for this field, or <c>null</c> if this descriptor does
|
||||
/// not support reflective access.
|
||||
/// Returns the accessor for this field.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// While a <see cref="FieldDescriptor"/> describes the field, it does not provide
|
||||
/// any way of obtaining or changing the value of the field within a specific message;
|
||||
/// that is the responsibility of the accessor.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The value returned by this property will be non-null for all regular fields. However,
|
||||
/// if a message containing a map field is introspected, the list of nested messages will include
|
||||
/// an auto-generated nested key/value pair message for the field. This is not represented in any
|
||||
/// generated type, and the value of the map field itself is represented by a dictionary in the
|
||||
/// reflection API. There are never instances of those "hidden" messages, so no accessor is provided
|
||||
/// and this property will return null.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IFieldAccessor Accessor { get { return accessor; } }
|
||||
|
||||
|
@ -281,7 +289,7 @@ namespace Google.Protobuf.Reflection
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a type.");
|
||||
throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not a type.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,8 +297,7 @@ namespace Google.Protobuf.Reflection
|
|||
{
|
||||
if (!(typeDescriptor is MessageDescriptor))
|
||||
{
|
||||
throw new DescriptorValidationException(this,
|
||||
"\"" + Proto.TypeName + "\" is not a message type.");
|
||||
throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not a message type.");
|
||||
}
|
||||
messageType = (MessageDescriptor) typeDescriptor;
|
||||
|
||||
|
@ -303,7 +310,7 @@ namespace Google.Protobuf.Reflection
|
|||
{
|
||||
if (!(typeDescriptor is EnumDescriptor))
|
||||
{
|
||||
throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not an enum type.");
|
||||
throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not an enum type.");
|
||||
}
|
||||
enumType = (EnumDescriptor) typeDescriptor;
|
||||
}
|
||||
|
@ -333,14 +340,16 @@ namespace Google.Protobuf.Reflection
|
|||
|
||||
private IFieldAccessor CreateAccessor(string propertyName)
|
||||
{
|
||||
if (containingType.GeneratedType == null || propertyName == null)
|
||||
// If we're given no property name, that's because we really don't want an accessor.
|
||||
// (At the moment, that means it's a map entry message...)
|
||||
if (propertyName == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var property = containingType.GeneratedType.GetProperty(propertyName);
|
||||
var property = containingType.ClrType.GetProperty(propertyName);
|
||||
if (property == null)
|
||||
{
|
||||
throw new DescriptorValidationException(this, "Property " + propertyName + " not found in " + containingType.GeneratedType);
|
||||
throw new DescriptorValidationException(this, $"Property {propertyName} not found in {containingType.ClrType}");
|
||||
}
|
||||
return IsMap ? new MapFieldAccessor(property, this)
|
||||
: IsRepeated ? new RepeatedFieldAccessor(property, this)
|
||||
|
|
|
@ -43,35 +43,26 @@ namespace Google.Protobuf.Reflection
|
|||
/// </summary>
|
||||
public sealed class FileDescriptor : IDescriptor
|
||||
{
|
||||
private readonly ByteString descriptorData;
|
||||
private readonly FileDescriptorProto proto;
|
||||
private readonly IList<MessageDescriptor> messageTypes;
|
||||
private readonly IList<EnumDescriptor> enumTypes;
|
||||
private readonly IList<ServiceDescriptor> services;
|
||||
private readonly IList<FileDescriptor> dependencies;
|
||||
private readonly IList<FileDescriptor> publicDependencies;
|
||||
private readonly DescriptorPool pool;
|
||||
|
||||
private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo)
|
||||
{
|
||||
this.descriptorData = descriptorData;
|
||||
this.pool = pool;
|
||||
this.proto = proto;
|
||||
this.dependencies = new ReadOnlyCollection<FileDescriptor>((FileDescriptor[]) dependencies.Clone());
|
||||
SerializedData = descriptorData;
|
||||
DescriptorPool = pool;
|
||||
Proto = proto;
|
||||
Dependencies = new ReadOnlyCollection<FileDescriptor>((FileDescriptor[]) dependencies.Clone());
|
||||
|
||||
publicDependencies = DeterminePublicDependencies(this, proto, dependencies, allowUnknownDependencies);
|
||||
PublicDependencies = DeterminePublicDependencies(this, proto, dependencies, allowUnknownDependencies);
|
||||
|
||||
pool.AddPackage(Package, this);
|
||||
|
||||
messageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageType,
|
||||
MessageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageType,
|
||||
(message, index) =>
|
||||
new MessageDescriptor(message, this, null, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedTypes[index]));
|
||||
new MessageDescriptor(message, this, null, index, generatedCodeInfo.NestedTypes[index]));
|
||||
|
||||
enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumType,
|
||||
EnumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumType,
|
||||
(enumType, index) =>
|
||||
new EnumDescriptor(enumType, this, null, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedEnums[index]));
|
||||
new EnumDescriptor(enumType, this, null, index, generatedCodeInfo.NestedEnums[index]));
|
||||
|
||||
services = DescriptorUtil.ConvertAndMakeReadOnly(proto.Service,
|
||||
Services = DescriptorUtil.ConvertAndMakeReadOnly(proto.Service,
|
||||
(service, index) =>
|
||||
new ServiceDescriptor(service, this, index));
|
||||
}
|
||||
|
@ -132,99 +123,63 @@ namespace Google.Protobuf.Reflection
|
|||
/// <value>
|
||||
/// The descriptor in its protocol message representation.
|
||||
/// </value>
|
||||
internal FileDescriptorProto Proto
|
||||
{
|
||||
get { return proto; }
|
||||
}
|
||||
internal FileDescriptorProto Proto { get; }
|
||||
|
||||
/// <value>
|
||||
/// The file name.
|
||||
/// </value>
|
||||
public string Name
|
||||
{
|
||||
get { return proto.Name; }
|
||||
}
|
||||
public string Name => Proto.Name;
|
||||
|
||||
/// <summary>
|
||||
/// The package as declared in the .proto file. This may or may not
|
||||
/// be equivalent to the .NET namespace of the generated classes.
|
||||
/// </summary>
|
||||
public string Package
|
||||
{
|
||||
get { return proto.Package; }
|
||||
}
|
||||
public string Package => Proto.Package;
|
||||
|
||||
/// <value>
|
||||
/// Unmodifiable list of top-level message types declared in this file.
|
||||
/// </value>
|
||||
public IList<MessageDescriptor> MessageTypes
|
||||
{
|
||||
get { return messageTypes; }
|
||||
}
|
||||
public IList<MessageDescriptor> MessageTypes { get; }
|
||||
|
||||
/// <value>
|
||||
/// Unmodifiable list of top-level enum types declared in this file.
|
||||
/// </value>
|
||||
public IList<EnumDescriptor> EnumTypes
|
||||
{
|
||||
get { return enumTypes; }
|
||||
}
|
||||
public IList<EnumDescriptor> EnumTypes { get; }
|
||||
|
||||
/// <value>
|
||||
/// Unmodifiable list of top-level services declared in this file.
|
||||
/// </value>
|
||||
public IList<ServiceDescriptor> Services
|
||||
{
|
||||
get { return services; }
|
||||
}
|
||||
public IList<ServiceDescriptor> Services { get; }
|
||||
|
||||
/// <value>
|
||||
/// Unmodifiable list of this file's dependencies (imports).
|
||||
/// </value>
|
||||
public IList<FileDescriptor> Dependencies
|
||||
{
|
||||
get { return dependencies; }
|
||||
}
|
||||
public IList<FileDescriptor> Dependencies { get; }
|
||||
|
||||
/// <value>
|
||||
/// Unmodifiable list of this file's public dependencies (public imports).
|
||||
/// </value>
|
||||
public IList<FileDescriptor> PublicDependencies
|
||||
{
|
||||
get { return publicDependencies; }
|
||||
}
|
||||
public IList<FileDescriptor> PublicDependencies { get; }
|
||||
|
||||
/// <value>
|
||||
/// The original serialized binary form of this descriptor.
|
||||
/// </value>
|
||||
public ByteString SerializedData
|
||||
{
|
||||
get { return descriptorData; }
|
||||
}
|
||||
public ByteString SerializedData { get; }
|
||||
|
||||
/// <value>
|
||||
/// Implementation of IDescriptor.FullName - just returns the same as Name.
|
||||
/// </value>
|
||||
string IDescriptor.FullName
|
||||
{
|
||||
get { return Name; }
|
||||
}
|
||||
string IDescriptor.FullName => Name;
|
||||
|
||||
/// <value>
|
||||
/// Implementation of IDescriptor.File - just returns this descriptor.
|
||||
/// </value>
|
||||
FileDescriptor IDescriptor.File
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
FileDescriptor IDescriptor.File => this;
|
||||
|
||||
/// <value>
|
||||
/// Pool containing symbol descriptors.
|
||||
/// </value>
|
||||
internal DescriptorPool DescriptorPool
|
||||
{
|
||||
get { return pool; }
|
||||
}
|
||||
internal DescriptorPool DescriptorPool { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Finds a type (message, enum, service or extension) in the file by name. Does not find nested types.
|
||||
|
@ -245,7 +200,7 @@ namespace Google.Protobuf.Reflection
|
|||
{
|
||||
name = Package + "." + name;
|
||||
}
|
||||
T result = pool.FindSymbol<T>(name);
|
||||
T result = DescriptorPool.FindSymbol<T>(name);
|
||||
if (result != null && result.File == this)
|
||||
{
|
||||
return result;
|
||||
|
@ -264,7 +219,7 @@ namespace Google.Protobuf.Reflection
|
|||
/// file's dependencies, in the exact order listed in the .proto file. May be null,
|
||||
/// in which case it is treated as an empty array.</param>
|
||||
/// <param name="allowUnknownDependencies">Whether unknown dependencies are ignored (true) or cause an exception to be thrown (false).</param>
|
||||
/// <param name="generatedCodeInfo">Reflection information, if any. May be null, specifically for non-generated code.</param>
|
||||
/// <param name="generatedCodeInfo">Details about generated code, for the purposes of reflection.</param>
|
||||
/// <exception cref="DescriptorValidationException">If <paramref name="proto"/> is not
|
||||
/// a valid descriptor. This can occur for a number of reasons, such as a field
|
||||
/// having an undefined type or because two messages were defined with the same name.</exception>
|
||||
|
@ -291,15 +246,17 @@ namespace Google.Protobuf.Reflection
|
|||
// need.
|
||||
if (dependencies.Length != proto.Dependency.Count)
|
||||
{
|
||||
throw new DescriptorValidationException(result,
|
||||
"Dependencies passed to FileDescriptor.BuildFrom() don't match " +
|
||||
"those listed in the FileDescriptorProto.");
|
||||
throw new DescriptorValidationException(
|
||||
result,
|
||||
"Dependencies passed to FileDescriptor.BuildFrom() don't match " +
|
||||
"those listed in the FileDescriptorProto.");
|
||||
}
|
||||
for (int i = 0; i < proto.Dependency.Count; i++)
|
||||
{
|
||||
if (dependencies[i].Name != proto.Dependency[i])
|
||||
{
|
||||
throw new DescriptorValidationException(result,
|
||||
throw new DescriptorValidationException(
|
||||
result,
|
||||
"Dependencies passed to FileDescriptor.BuildFrom() don't match " +
|
||||
"those listed in the FileDescriptorProto. Expected: " +
|
||||
proto.Dependency[i] + " but was: " + dependencies[i].Name);
|
||||
|
@ -312,28 +269,29 @@ namespace Google.Protobuf.Reflection
|
|||
|
||||
private void CrossLink()
|
||||
{
|
||||
foreach (MessageDescriptor message in messageTypes)
|
||||
foreach (MessageDescriptor message in MessageTypes)
|
||||
{
|
||||
message.CrossLink();
|
||||
}
|
||||
|
||||
foreach (ServiceDescriptor service in services)
|
||||
foreach (ServiceDescriptor service in Services)
|
||||
{
|
||||
service.CrossLink();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance for generated code.
|
||||
/// Creates a descriptor for generated code.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The <paramref name="generatedCodeInfo"/> parameter should be null for descriptors which don't correspond to
|
||||
/// generated types. Otherwise, it should be a <see cref="GeneratedCodeInfo"/> with nested types and nested
|
||||
/// enums corresponding to the types and enums contained within the file descriptor.
|
||||
/// This method is only designed to be used by the results of generating code with protoc,
|
||||
/// which creates the appropriate dependencies etc. It has to be public because the generated
|
||||
/// code is "external", but should not be called directly by end users.
|
||||
/// </remarks>
|
||||
public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData,
|
||||
FileDescriptor[] dependencies,
|
||||
GeneratedCodeInfo generatedCodeInfo)
|
||||
public static FileDescriptor FromGeneratedCode(
|
||||
byte[] descriptorData,
|
||||
FileDescriptor[] dependencies,
|
||||
GeneratedCodeInfo generatedCodeInfo)
|
||||
{
|
||||
FileDescriptorProto proto;
|
||||
try
|
||||
|
@ -345,8 +303,6 @@ namespace Google.Protobuf.Reflection
|
|||
throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// When building descriptors for generated code, we allow unknown
|
||||
|
@ -355,7 +311,7 @@ namespace Google.Protobuf.Reflection
|
|||
}
|
||||
catch (DescriptorValidationException e)
|
||||
{
|
||||
throw new ArgumentException("Invalid embedded descriptor for \"" + proto.Name + "\".", e);
|
||||
throw new ArgumentException($"Invalid embedded descriptor for \"{proto.Name}\".", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,7 +323,7 @@ namespace Google.Protobuf.Reflection
|
|||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "FileDescriptor for " + proto.Name;
|
||||
return $"FileDescriptor for {Name}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,3 +1,34 @@
|
|||
#region Copyright notice and license
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endregion
|
||||
using System;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
|
@ -20,31 +51,31 @@ namespace Google.Protobuf.Reflection
|
|||
/// <summary>
|
||||
/// Irrelevant for file descriptors; the parser for message descriptors.
|
||||
/// </summary>
|
||||
public MessageParser Parser { get; private set; }
|
||||
public MessageParser Parser { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Irrelevant for file descriptors; the CLR property names (in message descriptor field order)
|
||||
/// for fields in the message for message descriptors.
|
||||
/// </summary>
|
||||
public string[] PropertyNames { get; private set; }
|
||||
public string[] PropertyNames { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Irrelevant for file descriptors; the CLR property "base" names (in message descriptor oneof order)
|
||||
/// for oneofs in the message for message descriptors. It is expected that for a oneof name of "Foo",
|
||||
/// there will be a "FooCase" property and a "ClearFoo" method.
|
||||
/// </summary>
|
||||
public string[] OneofNames { get; private set; }
|
||||
public string[] OneofNames { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The reflection information for types within this file/message descriptor. Elements may be null
|
||||
/// if there is no corresponding generated type, e.g. for map entry types.
|
||||
/// </summary>
|
||||
public GeneratedCodeInfo[] NestedTypes { get; private set; }
|
||||
public GeneratedCodeInfo[] NestedTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The CLR types for enums within this file/message descriptor.
|
||||
/// </summary>
|
||||
public Type[] NestedEnums { get; private set; }
|
||||
public Type[] NestedEnums { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a GeneratedCodeInfo for a message descriptor, with nested types, nested enums, the CLR type, property names and oneof names.
|
||||
|
|
|
@ -56,153 +56,145 @@ namespace Google.Protobuf.Reflection
|
|||
"google/protobuf/type.proto",
|
||||
};
|
||||
|
||||
private readonly DescriptorProto proto;
|
||||
private readonly MessageDescriptor containingType;
|
||||
private readonly IList<MessageDescriptor> nestedTypes;
|
||||
private readonly IList<EnumDescriptor> enumTypes;
|
||||
private readonly IList<FieldDescriptor> fieldsInDeclarationOrder;
|
||||
private readonly IList<FieldDescriptor> fieldsInNumberOrder;
|
||||
private readonly IDictionary<string, FieldDescriptor> jsonFieldMap;
|
||||
private readonly FieldCollection fields;
|
||||
private readonly IList<OneofDescriptor> oneofs;
|
||||
// CLR representation of the type described by this descriptor, if any.
|
||||
private readonly Type generatedType;
|
||||
private readonly MessageParser parser;
|
||||
|
||||
internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, GeneratedCodeInfo generatedCodeInfo)
|
||||
: base(file, file.ComputeFullName(parent, proto.Name), typeIndex)
|
||||
{
|
||||
this.proto = proto;
|
||||
parser = generatedCodeInfo == null ? null : generatedCodeInfo.Parser;
|
||||
generatedType = generatedCodeInfo == null ? null : generatedCodeInfo.ClrType;
|
||||
Proto = proto;
|
||||
Parser = generatedCodeInfo?.Parser;
|
||||
ClrType = generatedCodeInfo?.ClrType;
|
||||
ContainingType = parent;
|
||||
|
||||
containingType = parent;
|
||||
|
||||
oneofs = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
// Note use of generatedCodeInfo. rather than generatedCodeInfo?. here... we don't expect
|
||||
// to see any nested oneofs, types or enums in "not actually generated" code... we do
|
||||
// expect fields though (for map entry messages).
|
||||
Oneofs = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
proto.OneofDecl,
|
||||
(oneof, index) =>
|
||||
new OneofDescriptor(oneof, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.OneofNames[index]));
|
||||
new OneofDescriptor(oneof, file, this, index, generatedCodeInfo.OneofNames[index]));
|
||||
|
||||
nestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
NestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
proto.NestedType,
|
||||
(type, index) =>
|
||||
new MessageDescriptor(type, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedTypes[index]));
|
||||
new MessageDescriptor(type, file, this, index, generatedCodeInfo.NestedTypes[index]));
|
||||
|
||||
enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
EnumTypes = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
proto.EnumType,
|
||||
(type, index) =>
|
||||
new EnumDescriptor(type, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedEnums[index]));
|
||||
new EnumDescriptor(type, file, this, index, generatedCodeInfo.NestedEnums[index]));
|
||||
|
||||
fieldsInDeclarationOrder = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
proto.Field,
|
||||
(field, index) =>
|
||||
new FieldDescriptor(field, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.PropertyNames[index]));
|
||||
new FieldDescriptor(field, file, this, index, generatedCodeInfo?.PropertyNames[index]));
|
||||
fieldsInNumberOrder = new ReadOnlyCollection<FieldDescriptor>(fieldsInDeclarationOrder.OrderBy(field => field.FieldNumber).ToArray());
|
||||
// TODO: Use field => field.Proto.JsonName when we're confident it's appropriate. (And then use it in the formatter, too.)
|
||||
jsonFieldMap = new ReadOnlyDictionary<string, FieldDescriptor>(fieldsInNumberOrder.ToDictionary(field => JsonFormatter.ToCamelCase(field.Name)));
|
||||
file.DescriptorPool.AddSymbol(this);
|
||||
fields = new FieldCollection(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the total number of nested types and enums, recursively.
|
||||
/// </summary>
|
||||
private int CountTotalGeneratedTypes()
|
||||
{
|
||||
return nestedTypes.Sum(nested => nested.CountTotalGeneratedTypes()) + enumTypes.Count;
|
||||
Fields = new FieldCollection(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The brief name of the descriptor's target.
|
||||
/// </summary>
|
||||
public override string Name { get { return proto.Name; } }
|
||||
public override string Name => Proto.Name;
|
||||
|
||||
internal DescriptorProto Proto { get { return proto; } }
|
||||
internal DescriptorProto Proto { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The generated type for this message, or <c>null</c> if the descriptor does not represent a generated type.
|
||||
/// The CLR type used to represent message instances from this descriptor.
|
||||
/// </summary>
|
||||
public Type GeneratedType { get { return generatedType; } }
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The value returned by this property will be non-null for all regular fields. However,
|
||||
/// if a message containing a map field is introspected, the list of nested messages will include
|
||||
/// an auto-generated nested key/value pair message for the field. This is not represented in any
|
||||
/// generated type, so this property will return null in such cases.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For wrapper types (<see cref="Google.Protobuf.WellKnownTypes.StringValue"/> and the like), the type returned here
|
||||
/// will be the generated message type, not the native type used by reflection for fields of those types. Code
|
||||
/// using reflection should call <see cref="IsWrapperType"/> to determine whether a message descriptor represents
|
||||
/// a wrapper type, and handle the result appropriately.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public Type ClrType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A parser for this message type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// As <see cref="MessageDescriptor"/> is not generic, this cannot be statically
|
||||
/// typed to the relevant type, but if <see cref="GeneratedType"/> returns a non-null value, the parser returned
|
||||
/// typed to the relevant type, but it should produce objects of a type compatible with <see cref="ClrType"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The value returned by this property will be non-null for all regular fields. However,
|
||||
/// if a message containing a map field is introspected, the list of nested messages will include
|
||||
/// an auto-generated nested key/value pair message for the field. No message parser object is created for
|
||||
/// such messages, so this property will return null in such cases.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For wrapper types (<see cref="Google.Protobuf.WellKnownTypes.StringValue"/> and the like), the parser returned here
|
||||
/// will be the generated message type, not the native type used by reflection for fields of those types. Code
|
||||
/// using reflection should call <see cref="IsWrapperType"/> to determine whether a message descriptor represents
|
||||
/// a wrapper type, and handle the result appropriately.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public MessageParser Parser { get { return parser; } }
|
||||
public MessageParser Parser { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this message is one of the "well known types" which may have runtime/protoc support.
|
||||
/// </summary>
|
||||
internal bool IsWellKnownType
|
||||
{
|
||||
get
|
||||
{
|
||||
return File.Package == "google.protobuf" && WellKnownTypeNames.Contains(File.Name);
|
||||
}
|
||||
}
|
||||
internal bool IsWellKnownType => File.Package == "google.protobuf" && WellKnownTypeNames.Contains(File.Name);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this message is one of the "wrapper types" used for fields which represent primitive values
|
||||
/// with the addition of presence.
|
||||
/// </summary>
|
||||
internal bool IsWrapperType => File.Package == "google.protobuf" && File.Name == "google/protobuf/wrappers.proto";
|
||||
|
||||
/// <value>
|
||||
/// If this is a nested type, get the outer descriptor, otherwise null.
|
||||
/// </value>
|
||||
public MessageDescriptor ContainingType
|
||||
{
|
||||
get { return containingType; }
|
||||
}
|
||||
public MessageDescriptor ContainingType { get; }
|
||||
|
||||
/// <value>
|
||||
/// A collection of fields, which can be retrieved by name or field number.
|
||||
/// </value>
|
||||
public FieldCollection Fields
|
||||
{
|
||||
get { return fields; }
|
||||
}
|
||||
public FieldCollection Fields { get; }
|
||||
|
||||
/// <value>
|
||||
/// An unmodifiable list of this message type's nested types.
|
||||
/// </value>
|
||||
public IList<MessageDescriptor> NestedTypes
|
||||
{
|
||||
get { return nestedTypes; }
|
||||
}
|
||||
public IList<MessageDescriptor> NestedTypes { get; }
|
||||
|
||||
/// <value>
|
||||
/// An unmodifiable list of this message type's enum types.
|
||||
/// </value>
|
||||
public IList<EnumDescriptor> EnumTypes
|
||||
{
|
||||
get { return enumTypes; }
|
||||
}
|
||||
public IList<EnumDescriptor> EnumTypes { get; }
|
||||
|
||||
/// <value>
|
||||
/// An unmodifiable list of the "oneof" field collections in this message type.
|
||||
/// </value>
|
||||
public IList<OneofDescriptor> Oneofs
|
||||
{
|
||||
get { return oneofs; }
|
||||
}
|
||||
public IList<OneofDescriptor> Oneofs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Finds a field by field name.
|
||||
/// </summary>
|
||||
/// <param name="name">The unqualified name of the field (e.g. "foo").</param>
|
||||
/// <returns>The field's descriptor, or null if not found.</returns>
|
||||
public FieldDescriptor FindFieldByName(String name)
|
||||
{
|
||||
return File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name);
|
||||
}
|
||||
public FieldDescriptor FindFieldByName(String name) => File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name);
|
||||
|
||||
/// <summary>
|
||||
/// Finds a field by field number.
|
||||
/// </summary>
|
||||
/// <param name="number">The field number within this message type.</param>
|
||||
/// <returns>The field's descriptor, or null if not found.</returns>
|
||||
public FieldDescriptor FindFieldByNumber(int number)
|
||||
{
|
||||
return File.DescriptorPool.FindFieldByNumber(this, number);
|
||||
}
|
||||
public FieldDescriptor FindFieldByNumber(int number) => File.DescriptorPool.FindFieldByNumber(this, number);
|
||||
|
||||
/// <summary>
|
||||
/// Finds a nested descriptor by name. The is valid for fields, nested
|
||||
|
@ -210,18 +202,15 @@ namespace Google.Protobuf.Reflection
|
|||
/// </summary>
|
||||
/// <param name="name">The unqualified name of the descriptor, e.g. "Foo"</param>
|
||||
/// <returns>The descriptor, or null if not found.</returns>
|
||||
public T FindDescriptor<T>(string name)
|
||||
where T : class, IDescriptor
|
||||
{
|
||||
return File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
|
||||
}
|
||||
public T FindDescriptor<T>(string name) where T : class, IDescriptor =>
|
||||
File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
|
||||
|
||||
/// <summary>
|
||||
/// Looks up and cross-links all fields and nested types.
|
||||
/// </summary>
|
||||
internal void CrossLink()
|
||||
{
|
||||
foreach (MessageDescriptor message in nestedTypes)
|
||||
foreach (MessageDescriptor message in NestedTypes)
|
||||
{
|
||||
message.CrossLink();
|
||||
}
|
||||
|
@ -231,7 +220,7 @@ namespace Google.Protobuf.Reflection
|
|||
field.CrossLink();
|
||||
}
|
||||
|
||||
foreach (OneofDescriptor oneof in oneofs)
|
||||
foreach (OneofDescriptor oneof in Oneofs)
|
||||
{
|
||||
oneof.CrossLink();
|
||||
}
|
||||
|
@ -253,10 +242,7 @@ namespace Google.Protobuf.Reflection
|
|||
/// Returns the fields in the message as an immutable list, in the order in which they
|
||||
/// are declared in the source .proto file.
|
||||
/// </value>
|
||||
public IList<FieldDescriptor> InDeclarationOrder()
|
||||
{
|
||||
return messageDescriptor.fieldsInDeclarationOrder;
|
||||
}
|
||||
public IList<FieldDescriptor> InDeclarationOrder() => messageDescriptor.fieldsInDeclarationOrder;
|
||||
|
||||
/// <value>
|
||||
/// Returns the fields in the message as an immutable list, in ascending field number
|
||||
|
@ -264,10 +250,7 @@ namespace Google.Protobuf.Reflection
|
|||
/// index in the list to the field number; to retrieve a field by field number, it is better
|
||||
/// to use the <see cref="FieldCollection"/> indexer.
|
||||
/// </value>
|
||||
public IList<FieldDescriptor> InFieldNumberOrder()
|
||||
{
|
||||
return messageDescriptor.fieldsInNumberOrder;
|
||||
}
|
||||
public IList<FieldDescriptor> InFieldNumberOrder() => messageDescriptor.fieldsInNumberOrder;
|
||||
|
||||
// TODO: consider making this public in the future. (Being conservative for now...)
|
||||
|
||||
|
@ -276,10 +259,7 @@ namespace Google.Protobuf.Reflection
|
|||
/// in the JSON representation to the field descriptors. For example, a field <c>foo_bar</c>
|
||||
/// in the message would result in an entry with a key <c>fooBar</c>.
|
||||
/// </value>
|
||||
internal IDictionary<string, FieldDescriptor> ByJsonName()
|
||||
{
|
||||
return messageDescriptor.jsonFieldMap;
|
||||
}
|
||||
internal IDictionary<string, FieldDescriptor> ByJsonName() => messageDescriptor.jsonFieldMap;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the descriptor for the field with the given number.
|
||||
|
|
|
@ -86,8 +86,7 @@ namespace Google.Protobuf.Reflection
|
|||
/// in a particular message.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The accessor used for reflective access, or <c>null</c> if reflection is not
|
||||
/// supported by this descriptor.
|
||||
/// The accessor used for reflective access.
|
||||
/// </value>
|
||||
public OneofAccessor Accessor { get { return accessor; } }
|
||||
|
||||
|
@ -106,19 +105,15 @@ namespace Google.Protobuf.Reflection
|
|||
|
||||
private OneofAccessor CreateAccessor(string clrName)
|
||||
{
|
||||
if (containingType.GeneratedType == null || clrName == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var caseProperty = containingType.GeneratedType.GetProperty(clrName + "Case");
|
||||
var caseProperty = containingType.ClrType.GetProperty(clrName + "Case");
|
||||
if (caseProperty == null)
|
||||
{
|
||||
throw new DescriptorValidationException(this, "Property " + clrName + "Case not found in " + containingType.GeneratedType);
|
||||
throw new DescriptorValidationException(this, $"Property {clrName}Case not found in {containingType.ClrType}");
|
||||
}
|
||||
var clearMethod = containingType.GeneratedType.GetMethod("Clear" + clrName);
|
||||
var clearMethod = containingType.ClrType.GetMethod("Clear" + clrName);
|
||||
if (clearMethod == null)
|
||||
{
|
||||
throw new DescriptorValidationException(this, "Method Clear" + clrName + " not found in " + containingType.GeneratedType);
|
||||
throw new DescriptorValidationException(this, $"Method Clear{clrName} not found in {containingType.ClrType}");
|
||||
}
|
||||
|
||||
return new OneofAccessor(caseProperty, clearMethod, this);
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQksKE2Nv",
|
||||
"bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAGgAQGiAgNHUEKqAh5Hb29n",
|
||||
"bGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Any), global::Google.Protobuf.WellKnownTypes.Any.Parser, new[]{ "TypeUrl", "Value" }, null, null, null)
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCSwoTY29t",
|
||||
"Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAaABAaICA0dQQqoCHkdvb2ds",
|
||||
"ZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Api), global::Google.Protobuf.WellKnownTypes.Api.Parser, new[]{ "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null),
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"ASgFQlAKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAaAB",
|
||||
"AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv",
|
||||
"dG8z"));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Duration), global::Google.Protobuf.WellKnownTypes.Duration.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"ZiIHCgVFbXB0eUJNChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
|
||||
"UAGgAQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNi",
|
||||
"BnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Empty), global::Google.Protobuf.WellKnownTypes.Empty.Parser, null, null, null, null)
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUJRChNjb20uZ29v",
|
||||
"Z2xlLnByb3RvYnVmQg5GaWVsZE1hc2tQcm90b1ABoAEBogIDR1BCqgIeR29v",
|
||||
"Z2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FieldMask), global::Google.Protobuf.WellKnownTypes.FieldMask.Parser, new[]{ "Paths" }, null, null, null)
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"CUJVChNjb20uZ29vZ2xlLnByb3RvYnVmQhJTb3VyY2VDb250ZXh0UHJvdG9Q",
|
||||
"AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
|
||||
"cHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.SourceContext), global::Google.Protobuf.WellKnownTypes.SourceContext.Parser, new[]{ "FileName" }, null, null, null)
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"QUxVRRAAQk4KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAGg",
|
||||
"AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnBy",
|
||||
"b3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), global::Google.Protobuf.WellKnownTypes.Struct.Parser, new[]{ "Fields" }, null, null, new pbr::GeneratedCodeInfo[] { null, }),
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"AiABKAVCUQoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
|
||||
"AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
|
||||
"cHJvdG8z"));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Timestamp), global::Google.Protobuf.WellKnownTypes.Timestamp.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"dGF4EhEKDVNZTlRBWF9QUk9UTzIQABIRCg1TWU5UQVhfUFJPVE8zEAFCTAoT",
|
||||
"Y29tLmdvb2dsZS5wcm90b2J1ZkIJVHlwZVByb3RvUAGgAQGiAgNHUEKqAh5H",
|
||||
"b29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, },
|
||||
new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), global::Google.Protobuf.WellKnownTypes.Type.Parser, new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null),
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Google.Protobuf.WellKnownTypes {
|
|||
"DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJQ",
|
||||
"ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAGgAQGiAgNH",
|
||||
"UEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
|
||||
descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
|
||||
new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.DoubleValue), global::Google.Protobuf.WellKnownTypes.DoubleValue.Parser, new[]{ "Value" }, null, null, null),
|
||||
|
|
|
@ -166,7 +166,7 @@ void ReflectionClassGenerator::WriteDescriptor(io::Printer* printer) {
|
|||
// -----------------------------------------------------------------
|
||||
// Invoke InternalBuildGeneratedFileFrom() to build the file.
|
||||
printer->Print(
|
||||
"descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,\n");
|
||||
"descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,\n");
|
||||
printer->Print(" new pbr::FileDescriptor[] { ");
|
||||
for (int i = 0; i < file_->dependency_count(); i++) {
|
||||
// descriptor.proto is special: we don't allow access to the generated code, but there's
|
||||
|
|
Loading…
Add table
Reference in a new issue