aboutsummaryrefslogtreecommitdiffhomepage
path: root/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
diff options
context:
space:
mode:
authorGravatar Jon Skeet <jonskeet@google.com>2015-07-20 19:24:31 +0100
committerGravatar Jon Skeet <jonskeet@google.com>2015-07-21 12:59:40 +0100
commit53c399a1d65df65e9f83a70b55041a01cf8d7489 (patch)
treebf3f738dd30295dc8ceb65478b9071d6d654e144 /csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
parent2ee4b5665520fe3245eb5e15df8bd35e0c539a07 (diff)
Revamp to reflection.
Changes in brief: 1. Descriptor is now the entry point for all reflection. 2. IReflectedMessage has gone; there's now a Descriptor property in IMessage, which is explicitly implemented (due to the static property). 3. FieldAccessorTable has gone away 4. IFieldAccessor and OneofFieldAccessor still exist; we *could* put the functionality straight into FieldDescriptor and OneofDescriptor... I'm unsure about that. 5. There's a temporary property MessageDescriptor.FieldAccessorsByFieldNumber to make the test changes small - we probably want this to go away 6. Discovery for delegates is now via attributes applied to properties and the Clear method of a oneof I'm happy with 1-3. 4 I'm unsure about - feedback welcome. 5 will go away 6 I'm unsure about, both in design and implementation. Should we have a ProtobufMessageAttribute too? Should we find all the relevant attributes in MessageDescriptor and pass them down, to avoid an O(N^2) scenario? Generated code changes coming in the next commit.
Diffstat (limited to 'csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs')
-rw-r--r--csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs34
1 files changed, 34 insertions, 0 deletions
diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
index e92dc8bb..b4cc0791 100644
--- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
@@ -32,6 +32,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq;
namespace Google.Protobuf.Reflection
{
@@ -40,6 +41,7 @@ namespace Google.Protobuf.Reflection
private readonly OneofDescriptorProto proto;
private MessageDescriptor containingType;
private IList<FieldDescriptor> fields;
+ private OneofAccessor accessor;
internal OneofDescriptor(OneofDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index)
: base(file, file.ComputeFullName(parent, proto.Name), index)
@@ -62,6 +64,8 @@ namespace Google.Protobuf.Reflection
public IList<FieldDescriptor> Fields { get { return fields; } }
+ public OneofAccessor Accessor { get { return accessor; } }
+
internal void CrossLink()
{
List<FieldDescriptor> fieldCollection = new List<FieldDescriptor>();
@@ -73,6 +77,36 @@ namespace Google.Protobuf.Reflection
}
}
fields = new ReadOnlyCollection<FieldDescriptor>(fieldCollection);
+ accessor = CreateAccessor();
+ }
+
+ private OneofAccessor CreateAccessor()
+ {
+ if (containingType.GeneratedType == null)
+ {
+ return null;
+ }
+ var caseProperty = containingType
+ .GeneratedType
+ .GetProperties()
+ .FirstOrDefault(p => p.IsDefined(typeof(ProtobufOneofAttribute), false) &&
+ p.GetCustomAttributes(typeof(ProtobufOneofAttribute), false).Cast<ProtobufOneofAttribute>().Single().Name == Name);
+ if (caseProperty == null)
+ {
+ return null;
+ }
+
+ var clearMethod = containingType
+ .GeneratedType
+ .GetMethods()
+ .FirstOrDefault(p => p.IsDefined(typeof(ProtobufOneofAttribute), false) &&
+ p.GetCustomAttributes(typeof(ProtobufOneofAttribute), false).Cast<ProtobufOneofAttribute>().Single().Name == Name);
+ if (clearMethod == null)
+ {
+ return null;
+ }
+
+ return new OneofAccessor(caseProperty, clearMethod, this);
}
}
}