aboutsummaryrefslogtreecommitdiffhomepage
path: root/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
diff options
context:
space:
mode:
Diffstat (limited to 'csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs')
-rw-r--r--csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs34
1 files changed, 31 insertions, 3 deletions
diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
index 1c22c460..9413cf61 100644
--- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
@@ -30,8 +30,10 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using Google.Protobuf.Collections;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace Google.Protobuf.Reflection
{
@@ -60,11 +62,15 @@ namespace Google.Protobuf.Reflection
private readonly IList<EnumDescriptor> enumTypes;
private readonly IList<FieldDescriptor> fields;
private readonly IList<OneofDescriptor> oneofs;
+ // CLR representation of the type described by this descriptor, if any.
+ private readonly Type generatedType;
+ private IDictionary<int, IFieldAccessor> fieldAccessorsByFieldNumber;
- internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex)
+ internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, IEnumerator<Type> generatedTypeIterator)
: base(file, file.ComputeFullName(parent, proto.Name), typeIndex)
{
this.proto = proto;
+ generatedType = ReflectionUtil.GetNextType(generatedTypeIterator);
containingType = parent;
oneofs = DescriptorUtil.ConvertAndMakeReadOnly(proto.OneofDecl,
@@ -73,11 +79,11 @@ namespace Google.Protobuf.Reflection
nestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.NestedType,
(type, index) =>
- new MessageDescriptor(type, file, this, index));
+ new MessageDescriptor(type, file, this, index, generatedTypeIterator));
enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumType,
(type, index) =>
- new EnumDescriptor(type, file, this, index));
+ new EnumDescriptor(type, file, this, index, ReflectionUtil.GetNextType(generatedTypeIterator)));
// TODO(jonskeet): Sort fields first?
fields = DescriptorUtil.ConvertAndMakeReadOnly(proto.Field,
@@ -85,6 +91,14 @@ namespace Google.Protobuf.Reflection
new FieldDescriptor(field, file, this, index));
file.DescriptorPool.AddSymbol(this);
}
+
+ /// <summary>
+ /// Returns the total number of nested types and enums, recursively.
+ /// </summary>
+ private int CountTotalGeneratedTypes()
+ {
+ return nestedTypes.Sum(nested => nested.CountTotalGeneratedTypes()) + enumTypes.Count;
+ }
/// <summary>
/// The brief name of the descriptor's target.
@@ -94,6 +108,11 @@ namespace Google.Protobuf.Reflection
internal DescriptorProto Proto { get { return proto; } }
/// <summary>
+ /// The generated type for this message, or <c>null</c> if the descriptor does not represent a generated type.
+ /// </summary>
+ public Type GeneratedType { get { return generatedType; } }
+
+ /// <summary>
/// Returns whether this message is one of the "well known types" which may have runtime/protoc support.
/// </summary>
internal bool IsWellKnownType
@@ -142,6 +161,13 @@ namespace Google.Protobuf.Reflection
}
/// <summary>
+ /// Returns a map from field number to accessor.
+ /// TODO: Revisit this. It's mostly in place to make the transition from FieldAccessorTable
+ /// to descriptor-based reflection simple in terms of tests. Work out what we really want.
+ /// </summary>
+ public IDictionary<int, IFieldAccessor> FieldAccessorsByFieldNumber { get { return fieldAccessorsByFieldNumber; } }
+
+ /// <summary>
/// Finds a field by field name.
/// </summary>
/// <param name="name">The unqualified name of the field (e.g. "foo").</param>
@@ -192,6 +218,8 @@ namespace Google.Protobuf.Reflection
{
oneof.CrossLink();
}
+
+ fieldAccessorsByFieldNumber = new ReadOnlyDictionary<int, IFieldAccessor>(fields.ToDictionary(field => field.FieldNumber, field => field.Accessor));
}
}
} \ No newline at end of file