فهرست منبع

Implemented GeneratedExtension, although list handling may be incorrect.

Jon Skeet 17 سال پیش
والد
کامیت
3f9a6f2116

+ 4 - 4
csharp/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs

@@ -522,8 +522,8 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     #region Nested types
     public static class Types {
-      public static readonly pb::GeneratedExtension<self::TestMessageSet, self::TestMessageSetExtension1> MessageSetExtension =
-            pb::GeneratedExtension.CreateExtension<self::TestMessageSet, self::TestMessageSetExtension1>(Descriptor.Extensions[0]);
+      public static readonly pb::GeneratedExtensionBase<self::TestMessageSet, self::TestMessageSetExtension1> MessageSetExtension =
+            pb::GeneratedSingleExtension<self::TestMessageSet, self::TestMessageSetExtension1>.CreateInstance(Descriptor.Extensions[0]);
     }
     #endregion
     
@@ -731,8 +731,8 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     #region Nested types
     public static class Types {
-      public static readonly pb::GeneratedExtension<self::TestMessageSet, self::TestMessageSetExtension2> MessageSetExtension =
-            pb::GeneratedExtension.CreateExtension<self::TestMessageSet, self::TestMessageSetExtension2>(Descriptor.Extensions[0]);
+      public static readonly pb::GeneratedExtensionBase<self::TestMessageSet, self::TestMessageSetExtension2> MessageSetExtension =
+            pb::GeneratedSingleExtension<self::TestMessageSet, self::TestMessageSetExtension2>.CreateInstance(Descriptor.Extensions[0]);
     }
     #endregion
     

+ 2 - 2
csharp/ProtocolBuffers.Test/TestProtos/UnitTestOptimizeForProtoFile.cs

@@ -81,8 +81,8 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     #region Nested types
     public static class Types {
-      public static readonly pb::GeneratedExtension<self::TestOptimizedForSize, int> TestExtension =
-            pb::GeneratedExtension.CreateExtension<self::TestOptimizedForSize, int>(Descriptor.Extensions[0]);
+      public static readonly pb::GeneratedExtensionBase<self::TestOptimizedForSize, int> TestExtension =
+            pb::GeneratedSingleExtension<self::TestOptimizedForSize, int>.CreateInstance(Descriptor.Extensions[0]);
     }
     #endregion
     

+ 144 - 144
csharp/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs

@@ -632,170 +632,170 @@ namespace Google.ProtocolBuffers.TestProtos {
     #endregion
     
     #region Extensions
-    /*public static readonly pb::GeneratedExtension<self::TestAllExtensions, int> OptionalInt32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, int>(Descriptor.Extensions[0]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, long> OptionalInt64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, long>(Descriptor.Extensions[1]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, uint> OptionalUint32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, uint>(Descriptor.Extensions[2]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, ulong> OptionalUint64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, ulong>(Descriptor.Extensions[3]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, int> OptionalSint32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, int>(Descriptor.Extensions[4]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, long> OptionalSint64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, long>(Descriptor.Extensions[5]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, uint> OptionalFixed32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, uint>(Descriptor.Extensions[6]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, ulong> OptionalFixed64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, ulong>(Descriptor.Extensions[7]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, int> OptionalSfixed32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, int>(Descriptor.Extensions[8]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, long> OptionalSfixed64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, long>(Descriptor.Extensions[9]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, float> OptionalFloatExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, float>(Descriptor.Extensions[10]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, double> OptionalDoubleExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, double>(Descriptor.Extensions[11]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, bool> OptionalBoolExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, bool>(Descriptor.Extensions[12]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, string> OptionalStringExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, string>(Descriptor.Extensions[13]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, pb::ByteString> OptionalBytesExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, pb::ByteString>(Descriptor.Extensions[14]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::OptionalGroup_extension> OptionalGroupExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::OptionalGroup_extension>(Descriptor.Extensions[15]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedMessage> OptionalNestedMessageExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedMessage>(Descriptor.Extensions[16]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::ForeignMessage> OptionalForeignMessageExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::ForeignMessage>(Descriptor.Extensions[17]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::ImportMessage> OptionalImportMessageExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::ImportMessage>(Descriptor.Extensions[18]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum> OptionalNestedEnumExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum>(Descriptor.Extensions[19]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::ForeignEnum> OptionalForeignEnumExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::ForeignEnum>(Descriptor.Extensions[20]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::ImportEnum> OptionalImportEnumExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::ImportEnum>(Descriptor.Extensions[21]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, string> OptionalStringPieceExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, string>(Descriptor.Extensions[22]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, string> OptionalCordExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, string>(Descriptor.Extensions[23]);
+    /*public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, int> OptionalInt32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[0]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, long> OptionalInt64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[1]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, uint> OptionalUint32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, uint>.CreateInstance(Descriptor.Extensions[2]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, ulong> OptionalUint64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, ulong>.CreateInstance(Descriptor.Extensions[3]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, int> OptionalSint32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[4]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, long> OptionalSint64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[5]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, uint> OptionalFixed32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, uint>.CreateInstance(Descriptor.Extensions[6]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, ulong> OptionalFixed64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, ulong>.CreateInstance(Descriptor.Extensions[7]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, int> OptionalSfixed32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[8]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, long> OptionalSfixed64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[9]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, float> OptionalFloatExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, float>.CreateInstance(Descriptor.Extensions[10]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, double> OptionalDoubleExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, double>.CreateInstance(Descriptor.Extensions[11]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, bool> OptionalBoolExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, bool>.CreateInstance(Descriptor.Extensions[12]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, string> OptionalStringExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[13]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, pb::ByteString> OptionalBytesExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, pb::ByteString>.CreateInstance(Descriptor.Extensions[14]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::OptionalGroup_extension> OptionalGroupExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::OptionalGroup_extension>.CreateInstance(Descriptor.Extensions[15]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::TestAllTypes.Types.NestedMessage> OptionalNestedMessageExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedMessage>.CreateInstance(Descriptor.Extensions[16]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::ForeignMessage> OptionalForeignMessageExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::ForeignMessage>.CreateInstance(Descriptor.Extensions[17]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::ImportMessage> OptionalImportMessageExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::ImportMessage>.CreateInstance(Descriptor.Extensions[18]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum> OptionalNestedEnumExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum>.CreateInstance(Descriptor.Extensions[19]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::ForeignEnum> OptionalForeignEnumExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::ForeignEnum>.CreateInstance(Descriptor.Extensions[20]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::ImportEnum> OptionalImportEnumExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::ImportEnum>.CreateInstance(Descriptor.Extensions[21]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, string> OptionalStringPieceExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[22]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, string> OptionalCordExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[23]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<int>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, int>(Descriptor.Extensions[24]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<int>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[24]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<long>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, long>(Descriptor.Extensions[25]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<long>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[25]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<uint>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, uint>(Descriptor.Extensions[26]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<uint>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, uint>.CreateInstance(Descriptor.Extensions[26]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<ulong>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, ulong>(Descriptor.Extensions[27]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<ulong>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, ulong>.CreateInstance(Descriptor.Extensions[27]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<int>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, int>(Descriptor.Extensions[28]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<int>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[28]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<long>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, long>(Descriptor.Extensions[29]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<long>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[29]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<uint>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, uint>(Descriptor.Extensions[30]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<uint>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, uint>.CreateInstance(Descriptor.Extensions[30]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<ulong>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, ulong>(Descriptor.Extensions[31]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<ulong>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, ulong>.CreateInstance(Descriptor.Extensions[31]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<int>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, int>(Descriptor.Extensions[32]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<int>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[32]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<long>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, long>(Descriptor.Extensions[33]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<long>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[33]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<float>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, float>(Descriptor.Extensions[34]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<float>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, float>.CreateInstance(Descriptor.Extensions[34]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<double>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, double>(Descriptor.Extensions[35]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<double>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, double>.CreateInstance(Descriptor.Extensions[35]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<bool>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, bool>(Descriptor.Extensions[36]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<bool>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, bool>.CreateInstance(Descriptor.Extensions[36]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<string>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, string>(Descriptor.Extensions[37]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<string>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[37]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<pb::ByteString>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, pb::ByteString>(Descriptor.Extensions[38]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<pb::ByteString>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, pb::ByteString>.CreateInstance(Descriptor.Extensions[38]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::RepeatedGroup_extension>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::RepeatedGroup_extension>(Descriptor.Extensions[39]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::RepeatedGroup_extension>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, self::RepeatedGroup_extension>.CreateInstance(Descriptor.Extensions[39]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::TestAllTypes.Types.NestedMessage>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedMessage>(Descriptor.Extensions[40]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::TestAllTypes.Types.NestedMessage>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedMessage>.CreateInstance(Descriptor.Extensions[40]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::ForeignMessage>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::ForeignMessage>(Descriptor.Extensions[41]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::ForeignMessage>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, self::ForeignMessage>.CreateInstance(Descriptor.Extensions[41]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::ImportMessage>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::ImportMessage>(Descriptor.Extensions[42]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::ImportMessage>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, self::ImportMessage>.CreateInstance(Descriptor.Extensions[42]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::TestAllTypes.Types.NestedEnum>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum>(Descriptor.Extensions[43]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::TestAllTypes.Types.NestedEnum>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum>.CreateInstance(Descriptor.Extensions[43]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::ForeignEnum>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::ForeignEnum>(Descriptor.Extensions[44]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::ForeignEnum>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, self::ForeignEnum>.CreateInstance(Descriptor.Extensions[44]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::ImportEnum>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::ImportEnum>(Descriptor.Extensions[45]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::ImportEnum>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, self::ImportEnum>.CreateInstance(Descriptor.Extensions[45]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<string>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, string>(Descriptor.Extensions[46]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<string>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[46]);
     public static readonly
-      pb::GeneratedExtension<self::TestAllExtensions, scg::IList<string>> name =
-          pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, string>(Descriptor.Extensions[47]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, int> DefaultInt32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, int>(Descriptor.Extensions[48]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, long> DefaultInt64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, long>(Descriptor.Extensions[49]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, uint> DefaultUint32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, uint>(Descriptor.Extensions[50]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, ulong> DefaultUint64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, ulong>(Descriptor.Extensions[51]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, int> DefaultSint32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, int>(Descriptor.Extensions[52]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, long> DefaultSint64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, long>(Descriptor.Extensions[53]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, uint> DefaultFixed32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, uint>(Descriptor.Extensions[54]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, ulong> DefaultFixed64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, ulong>(Descriptor.Extensions[55]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, int> DefaultSfixed32Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, int>(Descriptor.Extensions[56]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, long> DefaultSfixed64Extension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, long>(Descriptor.Extensions[57]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, float> DefaultFloatExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, float>(Descriptor.Extensions[58]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, double> DefaultDoubleExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, double>(Descriptor.Extensions[59]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, bool> DefaultBoolExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, bool>(Descriptor.Extensions[60]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, string> DefaultStringExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, string>(Descriptor.Extensions[61]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, pb::ByteString> DefaultBytesExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, pb::ByteString>(Descriptor.Extensions[62]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum> DefaultNestedEnumExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum>(Descriptor.Extensions[63]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::ForeignEnum> DefaultForeignEnumExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::ForeignEnum>(Descriptor.Extensions[64]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::ImportEnum> DefaultImportEnumExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::ImportEnum>(Descriptor.Extensions[65]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, string> DefaultStringPieceExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, string>(Descriptor.Extensions[66]);
-    public static readonly pb::GeneratedExtension<self::TestAllExtensions, string> DefaultCordExtension =
-          pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, string>(Descriptor.Extensions[67]);
-    public static readonly pb::GeneratedExtension<self::TestFieldOrderings, string> MyExtensionString =
-          pb::GeneratedExtension.CreateExtension<self::TestFieldOrderings, string>(Descriptor.Extensions[68]);
-    public static readonly pb::GeneratedExtension<self::TestFieldOrderings, int> MyExtensionInt =
-          pb::GeneratedExtension.CreateExtension<self::TestFieldOrderings, int>(Descriptor.Extensions[69]);
+      pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<string>> name =
+          pb::GeneratedRepeatExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[47]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, int> DefaultInt32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[48]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, long> DefaultInt64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[49]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, uint> DefaultUint32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, uint>.CreateInstance(Descriptor.Extensions[50]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, ulong> DefaultUint64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, ulong>.CreateInstance(Descriptor.Extensions[51]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, int> DefaultSint32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[52]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, long> DefaultSint64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[53]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, uint> DefaultFixed32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, uint>.CreateInstance(Descriptor.Extensions[54]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, ulong> DefaultFixed64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, ulong>.CreateInstance(Descriptor.Extensions[55]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, int> DefaultSfixed32Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, int>.CreateInstance(Descriptor.Extensions[56]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, long> DefaultSfixed64Extension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, long>.CreateInstance(Descriptor.Extensions[57]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, float> DefaultFloatExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, float>.CreateInstance(Descriptor.Extensions[58]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, double> DefaultDoubleExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, double>.CreateInstance(Descriptor.Extensions[59]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, bool> DefaultBoolExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, bool>.CreateInstance(Descriptor.Extensions[60]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, string> DefaultStringExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[61]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, pb::ByteString> DefaultBytesExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, pb::ByteString>.CreateInstance(Descriptor.Extensions[62]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum> DefaultNestedEnumExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::TestAllTypes.Types.NestedEnum>.CreateInstance(Descriptor.Extensions[63]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::ForeignEnum> DefaultForeignEnumExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::ForeignEnum>.CreateInstance(Descriptor.Extensions[64]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::ImportEnum> DefaultImportEnumExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, self::ImportEnum>.CreateInstance(Descriptor.Extensions[65]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, string> DefaultStringPieceExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[66]);
+    public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, string> DefaultCordExtension =
+          pb::GeneratedSingleExtension<self::TestAllExtensions, string>.CreateInstance(Descriptor.Extensions[67]);
+    public static readonly pb::GeneratedExtensionBase<self::TestFieldOrderings, string> MyExtensionString =
+          pb::GeneratedSingleExtension<self::TestFieldOrderings, string>.CreateInstance(Descriptor.Extensions[68]);
+    public static readonly pb::GeneratedExtensionBase<self::TestFieldOrderings, int> MyExtensionInt =
+          pb::GeneratedSingleExtension<self::TestFieldOrderings, int>.CreateInstance(Descriptor.Extensions[69]);
     */
     #endregion
     
@@ -6145,11 +6145,11 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     #region Nested types
     public static class Types {
-      public static readonly pb::GeneratedExtension<self::TestAllExtensions, self::TestRequired> Single =
-            pb::GeneratedExtension.CreateExtension<self::TestAllExtensions, self::TestRequired>(Descriptor.Extensions[0]);
+      public static readonly pb::GeneratedExtensionBase<self::TestAllExtensions, self::TestRequired> Single =
+            pb::GeneratedSingleExtension<self::TestAllExtensions, self::TestRequired>.CreateInstance(Descriptor.Extensions[0]);
       public static readonly
-        pb::GeneratedExtension<self::TestAllExtensions, scg::IList<self::TestRequired>> name =
-            pb::GeneratedExtension.CreateRepeatedExtension<self::TestAllExtensions, self::TestRequired>(Descriptor.Extensions[1]);
+        pb::GeneratedExtensionBase<self::TestAllExtensions, scg::IList<self::TestRequired>> name =
+            pb::GeneratedRepeatExtension<self::TestAllExtensions, self::TestRequired>.CreateInstance(Descriptor.Extensions[1]);
     }
     #endregion
     

+ 4 - 4
csharp/ProtocolBuffers/ExtendableMessage.cs

@@ -15,21 +15,21 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Checks if a singular extension is present.
     /// </summary>
-    public bool HasExtension(GeneratedExtension<TMessage, TBuilder> extension) {
+    public bool HasExtension(GeneratedExtensionBase<TMessage, TBuilder> extension) {
       return extensions.HasField(extension.Descriptor);
     }
 
     /// <summary>
     /// Returns the number of elements in a repeated extension.
     /// </summary>
-    public int GetExtensionCount<TExtension>(GeneratedExtension<TMessage, IList<TExtension>> extension) {
+    public int GetExtensionCount<TExtension>(GeneratedExtensionBase<TMessage, IList<TExtension>> extension) {
       return extensions.GetRepeatedFieldCount(extension.Descriptor);
     }
 
     /// <summary>
     /// Returns the value of an extension.
     /// </summary>
-    public TExtension GetExtension<TExtension>(GeneratedExtension<TMessage, TExtension> extension) {
+    public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TMessage, TExtension> extension) {
       object value = extensions[extension.Descriptor];
       if (value == null) {
         return (TExtension) extension.MessageDefaultInstance;
@@ -41,7 +41,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Returns one element of a repeated extension.
     /// </summary>
-    public TExtension GetExtension<TExtension>(GeneratedExtension<TMessage, IList<TExtension>> extension, int index) {
+    public TExtension GetExtension<TExtension>(GeneratedExtensionBase<TMessage, IList<TExtension>> extension, int index) {
       return (TExtension) extension.SingularFromReflectionType(extensions[extension.Descriptor, index]);
     }
 

+ 1 - 1
csharp/ProtocolBuffers/ExtensionRegistry.cs

@@ -88,7 +88,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Add an extension from a generated file to the registry.
     /// </summary>
-    public void Add<TContainer, TExtension> (GeneratedExtension<TContainer, TExtension> extension) 
+    public void Add<TContainer, TExtension> (GeneratedExtensionBase<TContainer, TExtension> extension) 
         where TContainer : IMessage<TContainer> {
       if (extension.Descriptor.MappedType == MappedType.Message) {
         Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance));

+ 0 - 97
csharp/ProtocolBuffers/GeneratedExtension.cs

@@ -1,97 +0,0 @@
-using Google.ProtocolBuffers.Descriptors;
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-
-namespace Google.ProtocolBuffers {
-
-  public static class GeneratedExtension {
-
-    public static GeneratedExtension<TContainer, TExtension> CreateExtension<TContainer, TExtension>(FieldDescriptor descriptor)
-        where TContainer : IMessage<TContainer> {
-      if (descriptor.IsRepeated) {
-        throw new ArgumentException("Must call CreateRepeatedGeneratedExtension() for repeated types.");
-      }
-      return new GeneratedExtension<TContainer, TExtension>(descriptor);
-    }
-
-    public static GeneratedExtension<TContainer, IList<TExtension>> CreateRepeatedExtension<TContainer, TExtension>(FieldDescriptor descriptor) 
-        where TContainer : IMessage<TContainer> {
-      if (descriptor.IsRepeated) {
-        throw new ArgumentException("Must call CreateRepeatedGeneratedExtension() for repeated types.");
-      }
-      return new GeneratedExtension<TContainer, IList<TExtension>>(descriptor);
-    }
-  }
-
-  /// <summary>
-  /// Base class for all generated extensions.
-  /// </summary>
-  /// <remarks>
-  /// The protocol compiler generates a static singleton instance of this
-  /// class for each extension. For exmaple, imagine a .proto file with:
-  /// <code>
-  /// message Foo {
-  ///   extensions 1000 to max
-  /// }
-  /// 
-  /// extend Foo {
-  ///   optional int32 bar;
-  /// }
-  /// </code>
-  /// Then MyProto.Foo.Bar has type GeneratedExtension&lt;MyProto.Foo,int&gt;.
-  /// <para />
-  /// In general, users should ignore the details of this type, and
-  /// simply use the static singletons as parmaeters to the extension accessors
-  /// in ExtendableMessage and ExtendableBuilder.
-  /// </remarks>
-  public class GeneratedExtension<TContainer, TExtension> where TContainer : IMessage<TContainer> {
-    private readonly IMessage messageDefaultInstance;
-    private readonly FieldDescriptor descriptor;
-
-    internal GeneratedExtension(FieldDescriptor descriptor) {
-      if (!descriptor.IsExtension) {
-        throw new ArgumentException("GeneratedExtension given a regular (non-extension) field.");
-      }
-
-      this.descriptor = descriptor;
-
-      switch (descriptor.MappedType) {
-        case MappedType.Message:
-          PropertyInfo defaultInstanceProperty = typeof(TExtension)
-              .GetProperty("DefaultInstance", BindingFlags.Static | BindingFlags.Public);
-          if (defaultInstanceProperty == null) {
-            throw new ArgumentException("No public static DefaultInstance property for type " + typeof(TExtension).Name);
-          }
-          messageDefaultInstance = (IMessage) defaultInstanceProperty.GetValue(null, null);
-          break;
-        case MappedType.Enum:
-          // FIXME(jonskeet): May not need this
-          //enumValueOf = getMethodOrDie(type, "valueOf",
-            //                           EnumValueDescriptor.class);
-          //enumGetValueDescriptor = getMethodOrDie(type, "getValueDescriptor");
-          messageDefaultInstance = null;
-          break;
-        default:
-          messageDefaultInstance = null;
-          break;
-      }
-    }
-
-    public FieldDescriptor Descriptor {
-      get { return descriptor; }
-    }
-
-    public IMessage MessageDefaultInstance {
-      get { return messageDefaultInstance; }
-    }
-
-    internal object SingularFromReflectionType(object p) {
-      throw new System.NotImplementedException();
-    }
-
-    internal object FromReflectionType(object value) {
-      throw new System.NotImplementedException();
-    }
-  }
-}

+ 88 - 0
csharp/ProtocolBuffers/GeneratedExtensionBase.cs

@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Base type for all generated extensions.
+  /// </summary>
+  /// <remarks>
+  /// The protocol compiler generates a static singleton instance of this
+  /// class for each extension. For exmaple, imagine a .proto file with:
+  /// <code>
+  /// message Foo {
+  ///   extensions 1000 to max
+  /// }
+  /// 
+  /// extend Foo {
+  ///   optional int32 bar;
+  /// }
+  /// </code>
+  /// Then MyProto.Foo.Bar has type GeneratedExtensionBase&lt;MyProto.Foo,int&gt;.
+  /// <para />
+  /// In general, users should ignore the details of this type, and
+  /// simply use the static singletons as parameters to the extension accessors
+  /// in ExtendableMessage and ExtendableBuilder.
+  /// The interface implemented by both GeneratedException and GeneratedRepeatException,
+  /// to make it easier to cope with repeats separately.
+  /// </remarks>
+  public abstract class GeneratedExtensionBase<TContainer, TExtension> {
+
+    private readonly FieldDescriptor descriptor;
+    private readonly IMessage messageDefaultInstance;
+
+    protected GeneratedExtensionBase(FieldDescriptor descriptor) {
+      if (!descriptor.IsExtension) {
+        throw new ArgumentException("GeneratedExtension given a regular (non-extension) field.");
+      }
+
+      this.descriptor = descriptor;
+      if (descriptor.MappedType == MappedType.Message) {
+        PropertyInfo defaultInstanceProperty = typeof(TExtension)
+            .GetProperty("DefaultInstance", BindingFlags.Static | BindingFlags.Public);
+        if (defaultInstanceProperty == null) {
+          throw new ArgumentException("No public static DefaultInstance property for type " + typeof(TExtension).Name);
+        }
+        messageDefaultInstance = (IMessage)defaultInstanceProperty.GetValue(null, null);
+      }
+    }
+
+    public FieldDescriptor Descriptor {
+      get { return descriptor; }
+    }
+
+    /// <summary>
+    /// Returns the default message instance for extensions which are message types.
+    /// </summary>
+    public IMessage MessageDefaultInstance {
+      get { return messageDefaultInstance; }
+    }
+
+    public object SingularFromReflectionType(object value) {
+      switch (Descriptor.MappedType) {
+        case MappedType.Message:
+          if (value is TExtension) {
+            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.CreateBuilderForType()
+                           .MergeFrom((IMessage)value).Build();
+          }
+        case MappedType.Enum:
+          // Just return a boxed int - that can be unboxed to the enum
+          return ((EnumValueDescriptor) value).Number;
+        default:
+          return value;
+      }
+    }
+
+    public abstract object FromReflectionType(object value);
+  }
+}

+ 42 - 0
csharp/ProtocolBuffers/GeneratedRepeatException.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using Google.ProtocolBuffers.Descriptors;
+using System.Collections;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Class used to represent repeat extensions in generated classes.
+  /// </summary>
+  public class GeneratedRepeatExtension<TContainer, TExtensionElement> : GeneratedExtensionBase<TContainer, IList<TExtensionElement>> {
+    private GeneratedRepeatExtension(FieldDescriptor field) : base(field) {
+    }
+
+    public static GeneratedExtensionBase<TContainer, IList<TExtensionElement>> CreateInstance(FieldDescriptor descriptor) {
+      if (descriptor.IsRepeated) {
+        throw new ArgumentException("Must call GeneratedRepeatExtension.CreateInstance() for repeated types.");
+      }
+      return new GeneratedRepeatExtension<TContainer, TExtensionElement>(descriptor);
+    }
+
+    /// <summary>
+    /// Converts the list to the right type.
+    /// TODO(jonskeet): Check where this is used, and whether we need to convert
+    /// for primitive types.
+    /// </summary>
+    /// <param name="value"></param>
+    /// <returns></returns>
+    public override object FromReflectionType(object value) {
+      if (Descriptor.MappedType == MappedType.Message ||
+          Descriptor.MappedType == MappedType.Enum) {
+        // Must convert the whole list.
+        List<TExtensionElement> result = new List<TExtensionElement>();
+        foreach (object element in (IEnumerable) value) {
+          ((IList) result).Add(SingularFromReflectionType(element));
+        }
+        return result;
+      } else {
+        return value;
+      }
+    }
+  }
+}

+ 26 - 0
csharp/ProtocolBuffers/GeneratedSingleExtension.cs

@@ -0,0 +1,26 @@
+using System;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers {
+
+  /// <summary>
+  /// Generated extension for a singular field.
+  /// </remarks>
+  public class GeneratedSingleExtension<TContainer, TExtension> : GeneratedExtensionBase<TContainer, TExtension>    
+      where TContainer : IMessage<TContainer> {
+
+    internal GeneratedSingleExtension(FieldDescriptor descriptor) : base(descriptor) {
+    }
+
+    public static GeneratedSingleExtension<TContainer, TExtension> CreateInstance(FieldDescriptor descriptor) {
+      if (descriptor.IsRepeated) {
+        throw new ArgumentException("Must call GeneratedRepeateExtension.CreateInstance() for repeated types.");
+      }
+      return new GeneratedSingleExtension<TContainer, TExtension>(descriptor);
+    }
+
+    public override object FromReflectionType(object value) {
+      return base.SingularFromReflectionType(value);
+    }
+  }
+}

+ 3 - 1
csharp/ProtocolBuffers/ProtocolBuffers.csproj

@@ -82,9 +82,11 @@
     <Compile Include="FieldAccess\RepeatedMessageAccessor.cs" />
     <Compile Include="FieldSet.cs" />
     <Compile Include="GeneratedBuilder.cs" />
-    <Compile Include="GeneratedExtension.cs" />
+    <Compile Include="GeneratedSingleExtension.cs" />
     <Compile Include="GeneratedMessage.cs" />
+    <Compile Include="GeneratedRepeatException.cs" />
     <Compile Include="IBuilder.cs" />
+    <Compile Include="GeneratedExtensionBase.cs" />
     <Compile Include="IMessage.cs" />
     <Compile Include="InvalidProtocolBufferException.cs" />
     <Compile Include="IRpcChannel.cs" />

+ 4 - 4
src/google/protobuf/compiler/csharp/csharp_extension.cc

@@ -57,12 +57,12 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
   if (descriptor_->is_repeated()) {
     printer->Print(vars,
       "public static readonly\r\n"
-      "  pb::GeneratedExtension<$containing_type$, scg::IList<$type$>> name =\r\n"
-      "      pb::GeneratedExtension.CreateRepeatedExtension<$containing_type$, $type$>(Descriptor.Extensions[$index$]);\r\n");
+      "  pb::GeneratedExtensionBase<$containing_type$, scg::IList<$type$>> name =\r\n"
+      "      pb::GeneratedRepeatExtension<$containing_type$, $type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n");
   } else {
     printer->Print(vars,
-      "public static readonly pb::GeneratedExtension<$containing_type$, $type$> $name$ =\r\n"
-      "      pb::GeneratedExtension.CreateExtension<$containing_type$, $type$>(Descriptor.Extensions[$index$]);\r\n");
+      "public static readonly pb::GeneratedExtensionBase<$containing_type$, $type$> $name$ =\r\n"
+      "      pb::GeneratedSingleExtension<$containing_type$, $type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n");
   }
 }