aboutsummaryrefslogtreecommitdiffhomepage
path: root/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
diff options
context:
space:
mode:
authorGravatar Jon Skeet <jonskeet@google.com>2015-11-19 17:13:38 +0000
committerGravatar Jon Skeet <jonskeet@google.com>2015-11-22 16:25:44 +0000
commit72ec33676fd40ccfe719ace162fcf859ae9251bc (patch)
treea90f4be5e939a8a55175aa1d4e8e54c7f919feb1 /csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
parentd6202a9b8948d5a2d5436e3b35b175ed9b8a9fd1 (diff)
Tidy up reflection in advance of attempting to implement DynamicMessage.
There are corner cases where MessageDescriptor.{ClrType,Parser} will return null, and these are now documented. However, normally they *should* be implemented, even for descriptors of for dynamic messages. Ditto FieldDescriptor.Accessor. We'll still need a fair amount of work to implement dynamic messages, but this change means that the public API will be remain intact. Additionally, this change starts making use of C# 6 features in the files that it touches. This is far from exhaustive, and later PRs will have more. Generated code changes coming in the next commit.
Diffstat (limited to 'csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs')
-rw-r--r--csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs128
1 files changed, 42 insertions, 86 deletions
diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
index 549dfe28..48ee5596 100644
--- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
@@ -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>