From 80824a51c2730cad30395cf8c54b2a44546cd744 Mon Sep 17 00:00:00 2001 From: csharptest Date: Sun, 7 Nov 2010 17:25:47 -0600 Subject: First Lite tests are passing. --- src/ProtocolBuffers/Descriptors/EnumDescriptor.cs | 3 + src/ProtocolBuffers/EnumLite.cs | 11 +++- src/ProtocolBuffers/ExtendableBuilderLite.cs | 6 +- src/ProtocolBuffers/ExtendableMessageLite.cs | 4 +- src/ProtocolBuffers/GeneratedExtensionLite.cs | 73 ++++++++++++++++++++++- 5 files changed, 88 insertions(+), 9 deletions(-) (limited to 'src/ProtocolBuffers') diff --git a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs index c121c7e6..d6ef4e17 100644 --- a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs +++ b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs @@ -87,6 +87,9 @@ namespace Google.ProtocolBuffers.Descriptors { return File.DescriptorPool.FindEnumValueByNumber(this, number); } + IEnumLite IEnumLiteMap.FindValueByNumber(int number) { + return FindValueByNumber(number); + } /// /// Finds an enum value by name. /// diff --git a/src/ProtocolBuffers/EnumLite.cs b/src/ProtocolBuffers/EnumLite.cs index 92187b38..a408fd43 100644 --- a/src/ProtocolBuffers/EnumLite.cs +++ b/src/ProtocolBuffers/EnumLite.cs @@ -57,11 +57,12 @@ namespace Google.ProtocolBuffers { /// public interface IEnumLiteMap : IEnumLiteMap where T : IEnumLite { - T FindValueByNumber(int number); + new T FindValueByNumber(int number); } public interface IEnumLiteMap { bool IsValidValue(IEnumLite value); + IEnumLite FindValueByNumber(int number); } public class EnumLiteMap : IEnumLiteMap @@ -88,12 +89,16 @@ namespace Google.ProtocolBuffers { items.Add(evalue.ToInt32(CultureInfo.InvariantCulture), new EnumValue(evalue.ToInt32(CultureInfo.InvariantCulture))); } - IEnumLite IEnumLiteMap.FindValueByNumber(int number) { + IEnumLite IEnumLiteMap.FindValueByNumber(int number) { + return FindValueByNumber(number); + } + + public IEnumLite FindValueByNumber(int number) { IEnumLite val; return items.TryGetValue(number, out val) ? val : null; } - bool IEnumLiteMap.IsValidValue(IEnumLite value) { + public bool IsValidValue(IEnumLite value) { return items.ContainsKey(value.Number); } } diff --git a/src/ProtocolBuffers/ExtendableBuilderLite.cs b/src/ProtocolBuffers/ExtendableBuilderLite.cs index 815b51b3..df0323ba 100644 --- a/src/ProtocolBuffers/ExtendableBuilderLite.cs +++ b/src/ProtocolBuffers/ExtendableBuilderLite.cs @@ -76,7 +76,7 @@ namespace Google.ProtocolBuffers { public TBuilder SetExtension(GeneratedExtensionLite extension, TExtension value) { ExtendableMessageLite message = MessageBeingBuilt; message.VerifyExtensionContainingType(extension); - message.Extensions[extension.Descriptor] = (value); + message.Extensions[extension.Descriptor] = extension.ToReflectionType(value); return ThisBuilder; } @@ -86,7 +86,7 @@ namespace Google.ProtocolBuffers { public TBuilder SetExtension(GeneratedExtensionLite> extension, int index, TExtension value) { ExtendableMessageLite message = MessageBeingBuilt; message.VerifyExtensionContainingType(extension); - message.Extensions[extension.Descriptor, index] = (value); + message.Extensions[extension.Descriptor, index] = extension.SingularToReflectionType(value); return ThisBuilder; } @@ -96,7 +96,7 @@ namespace Google.ProtocolBuffers { public ExtendableBuilderLite AddExtension(GeneratedExtensionLite> extension, TExtension value) { ExtendableMessageLite message = MessageBeingBuilt; message.VerifyExtensionContainingType(extension); - message.Extensions.AddRepeatedField(extension.Descriptor, (value)); + message.Extensions.AddRepeatedField(extension.Descriptor, extension.SingularToReflectionType(value)); return this; } diff --git a/src/ProtocolBuffers/ExtendableMessageLite.cs b/src/ProtocolBuffers/ExtendableMessageLite.cs index 4cd90e48..fc2ccb6c 100644 --- a/src/ProtocolBuffers/ExtendableMessageLite.cs +++ b/src/ProtocolBuffers/ExtendableMessageLite.cs @@ -74,7 +74,7 @@ namespace Google.ProtocolBuffers { if (value == null) { return extension.DefaultValue; } else { - return (TExtension)value; + return (TExtension)extension.FromReflectionType(value); } } @@ -83,7 +83,7 @@ namespace Google.ProtocolBuffers { /// public TExtension GetExtension(GeneratedExtensionLite> extension, int index) { VerifyExtensionContainingType(extension); - return (TExtension)extensions[extension.Descriptor, index]; + return (TExtension)extension.SingularFromReflectionType(extensions[extension.Descriptor, index]); } /// diff --git a/src/ProtocolBuffers/GeneratedExtensionLite.cs b/src/ProtocolBuffers/GeneratedExtensionLite.cs index e27dff72..c2ba5627 100644 --- a/src/ProtocolBuffers/GeneratedExtensionLite.cs +++ b/src/ProtocolBuffers/GeneratedExtensionLite.cs @@ -33,6 +33,7 @@ #endregion using System; +using System.Collections; using System.Collections.Generic; using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Descriptors; @@ -224,8 +225,78 @@ namespace Google.ProtocolBuffers { } } + /// + /// Converts from the type used by the native accessors to the type + /// used by reflection accessors. For example, the reflection accessors + /// for enums use EnumValueDescriptors but the native accessors use + /// the generated enum type. + /// + public object ToReflectionType(object value) { + if (descriptor.IsRepeated) { + if (descriptor.MappedType == MappedType.Enum) { + // Must convert the whole list. + IList result = new List(); + foreach (object element in (IEnumerable)value) { + result.Add(SingularToReflectionType(element)); + } + return result; + } else { + return value; + } + } else { + return SingularToReflectionType(value); + } + } + + /// + /// Like ToReflectionType(object) but for a single element. + /// + internal Object SingularToReflectionType(object value) { + return descriptor.MappedType == MappedType.Enum + ? descriptor.EnumType.FindValueByNumber((int)value) + : value; + } + + public object FromReflectionType(object value) { + if (descriptor.IsRepeated) { + if (Descriptor.MappedType == MappedType.Message || + Descriptor.MappedType == MappedType.Enum) { + // Must convert the whole list. + List result = new List(); + foreach (object element in (IEnumerable)value) { + result.Add((TExtensionType)SingularFromReflectionType(element)); + } + return result; + } else { + return value; + } + } else { + return SingularFromReflectionType(value); + } + } + public object SingularFromReflectionType(object value) { - return value; + switch (Descriptor.MappedType) { + case MappedType.Message: + if (value is TExtensionType) { + return value; + } else { + // It seems the copy of the embedded message stored inside the + // extended message is not of the exact type the user was + // expecting. This can happen if a user defines a + // GeneratedExtension manually and gives it a different type. + // This should not happen in normal use. But, to be nice, we'll + // copy the message to whatever type the caller was expecting. + return MessageDefaultInstance.WeakCreateBuilderForType() + .WeakMergeFrom((IMessageLite)value).WeakBuild(); + } + case MappedType.Enum: + // Just return a boxed int - that can be unboxed to the enum + IEnumLite enumValue = (IEnumLite)value; + return enumValue.Number; + default: + return value; + } } } } \ No newline at end of file -- cgit v1.2.3