diff options
author | Jie Luo <anandolee@gmail.com> | 2015-04-29 11:33:07 -0700 |
---|---|---|
committer | Jie Luo <anandolee@gmail.com> | 2015-04-29 11:33:07 -0700 |
commit | c5c9c6a7e05a44724bc4bc6192ff995b4398d559 (patch) | |
tree | bb4eab9a4c4830b7e6d91f83b1309498a9e41578 /csharp/src/ProtocolBuffers/FieldAccess | |
parent | 8bae6c09bc8c8be808f0acc9b2ad4c9811493060 (diff) | |
download | protobuf-c5c9c6a7e05a44724bc4bc6192ff995b4398d559.tar.gz protobuf-c5c9c6a7e05a44724bc4bc6192ff995b4398d559.tar.bz2 protobuf-c5c9c6a7e05a44724bc4bc6192ff995b4398d559.zip |
field presence Reflection and tests
Diffstat (limited to 'csharp/src/ProtocolBuffers/FieldAccess')
4 files changed, 31 insertions, 10 deletions
diff --git a/csharp/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs b/csharp/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs index 6ba039c1..60b032e2 100644 --- a/csharp/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs +++ b/csharp/src/ProtocolBuffers/FieldAccess/FieldAccessorTable.cs @@ -68,16 +68,21 @@ namespace Google.ProtocolBuffers.FieldAccess {
this.descriptor = descriptor;
accessors = new IFieldAccessor<TMessage, TBuilder>[descriptor.Fields.Count];
+ bool supportFieldPresence = false;
+ if (descriptor.File.GetSyntax() == FileDescriptor.Syntax.PROTO2)
+ {
+ supportFieldPresence = true;
+ }
for (int i = 0; i < accessors.Length; i++)
{
- accessors[i] = CreateAccessor(descriptor.Fields[i], propertyNames[i]);
+ accessors[i] = CreateAccessor(descriptor.Fields[i], propertyNames[i], supportFieldPresence);
}
}
/// <summary>
/// Creates an accessor for a single field
/// </summary>
- private static IFieldAccessor<TMessage, TBuilder> CreateAccessor(FieldDescriptor field, string name)
+ private static IFieldAccessor<TMessage, TBuilder> CreateAccessor(FieldDescriptor field, string name, bool supportFieldPresence)
{
if (field.IsRepeated)
{
@@ -98,9 +103,9 @@ namespace Google.ProtocolBuffers.FieldAccess case MappedType.Message:
return new SingleMessageAccessor<TMessage, TBuilder>(name);
case MappedType.Enum:
- return new SingleEnumAccessor<TMessage, TBuilder>(field, name);
+ return new SingleEnumAccessor<TMessage, TBuilder>(field, name, supportFieldPresence);
default:
- return new SinglePrimitiveAccessor<TMessage, TBuilder>(name);
+ return new SinglePrimitiveAccessor<TMessage, TBuilder>(field, name, supportFieldPresence);
}
}
}
diff --git a/csharp/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs b/csharp/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs index 6327cc55..e63f717c 100644 --- a/csharp/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs +++ b/csharp/src/ProtocolBuffers/FieldAccess/SingleEnumAccessor.cs @@ -42,7 +42,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
private readonly EnumDescriptor enumDescriptor;
- internal SingleEnumAccessor(FieldDescriptor field, string name) : base(name)
+ internal SingleEnumAccessor(FieldDescriptor field, string name, bool supportFieldPresence) : base(field, name, supportFieldPresence)
{
enumDescriptor = field.EnumType;
}
diff --git a/csharp/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs b/csharp/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs index 6bf48a0c..0ec2b0b7 100644 --- a/csharp/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs +++ b/csharp/src/ProtocolBuffers/FieldAccess/SingleMessageAccessor.cs @@ -48,7 +48,7 @@ namespace Google.ProtocolBuffers.FieldAccess /// </summary>
private readonly Func<IBuilder> createBuilderDelegate;
- internal SingleMessageAccessor(string name) : base(name)
+ internal SingleMessageAccessor(string name) : base(null, name, true)
{
MethodInfo createBuilderMethod = ClrType.GetMethod("CreateBuilder", ReflectionUtil.EmptyTypes);
if (createBuilderMethod == null)
diff --git a/csharp/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs b/csharp/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs index e5a07540..b964066d 100644 --- a/csharp/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs +++ b/csharp/src/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs @@ -31,6 +31,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Reflection;
+using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers.FieldAccess
{
@@ -42,6 +43,7 @@ namespace Google.ProtocolBuffers.FieldAccess where TBuilder : IBuilder<TMessage, TBuilder>
{
private readonly Type clrType;
+ private readonly FieldDescriptor field;
private readonly Func<TMessage, object> getValueDelegate;
private readonly Action<TBuilder, object> setValueDelegate;
private readonly Func<TMessage, bool> hasDelegate;
@@ -56,18 +58,28 @@ namespace Google.ProtocolBuffers.FieldAccess get { return clrType; }
}
- internal SinglePrimitiveAccessor(string name)
+ internal SinglePrimitiveAccessor(FieldDescriptor fieldDesriptor, string name, bool supportFieldPresence)
{
+ field = fieldDesriptor;
PropertyInfo messageProperty = typeof(TMessage).GetProperty(name, null, ReflectionUtil.EmptyTypes);
PropertyInfo builderProperty = typeof(TBuilder).GetProperty(name, null, ReflectionUtil.EmptyTypes);
- PropertyInfo hasProperty = typeof(TMessage).GetProperty("Has" + name);
MethodInfo clearMethod = typeof(TBuilder).GetMethod("Clear" + name);
- if (messageProperty == null || builderProperty == null || hasProperty == null || clearMethod == null)
+ if (messageProperty == null || builderProperty == null || clearMethod == null)
{
throw new ArgumentException("Not all required properties/methods available");
}
+
+ if (supportFieldPresence)
+ {
+ PropertyInfo hasProperty = typeof(TMessage).GetProperty("Has" + name);
+ if (hasProperty == null)
+ {
+ throw new ArgumentException("Has properties not available");
+ }
+ hasDelegate = ReflectionUtil.CreateDelegateFunc<TMessage, bool>(hasProperty.GetGetMethod());
+ }
+
clrType = messageProperty.PropertyType;
- hasDelegate = ReflectionUtil.CreateDelegateFunc<TMessage, bool>(hasProperty.GetGetMethod());
clearDelegate = ReflectionUtil.CreateDelegateFunc<TBuilder, IBuilder>(clearMethod);
getValueDelegate = ReflectionUtil.CreateUpcastDelegate<TMessage>(messageProperty.GetGetMethod());
setValueDelegate = ReflectionUtil.CreateDowncastDelegate<TBuilder>(builderProperty.GetSetMethod());
@@ -75,6 +87,10 @@ namespace Google.ProtocolBuffers.FieldAccess public bool Has(TMessage message)
{
+ if (hasDelegate == null)
+ {
+ return !GetValue(message).Equals(field.DefaultValue);
+ }
return hasDelegate(message);
}
|