Browse Source

Add private "_Extensions" property to speed up IsInitialized checks

Sydney Acksman 6 years ago
parent
commit
ebf0bfaed8

+ 2 - 0
csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto2.cs

@@ -227,6 +227,7 @@ namespace ProtobufTestMessages.Proto2 {
     private static readonly pb::MessageParser<TestAllTypesProto2> _parser = new pb::MessageParser<TestAllTypesProto2>(() => new TestAllTypesProto2());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestAllTypesProto2> _extensions;
+    private pb::ExtensionSet<TestAllTypesProto2> _Extensions => _extensions;
     private int _hasBits0;
     private int _hasBits1;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3703,6 +3704,7 @@ namespace ProtobufTestMessages.Proto2 {
         private static readonly pb::MessageParser<MessageSetCorrect> _parser = new pb::MessageParser<MessageSetCorrect>(() => new MessageSetCorrect());
         private pb::UnknownFieldSet _unknownFields;
         private pb::ExtensionSet<MessageSetCorrect> _extensions;
+        private pb::ExtensionSet<MessageSetCorrect> _Extensions => _extensions;
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
         public static pb::MessageParser<MessageSetCorrect> Parser { get { return _parser; } }
 

+ 10 - 0
csharp/src/Google.Protobuf.Test/TestProtos/Unittest.cs

@@ -5139,6 +5139,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestAllExtensions> _parser = new pb::MessageParser<TestAllExtensions>(() => new TestAllExtensions());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestAllExtensions> _extensions;
+    private pb::ExtensionSet<TestAllExtensions> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestAllExtensions> Parser { get { return _parser; } }
 
@@ -5913,6 +5914,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestGroupExtension> _parser = new pb::MessageParser<TestGroupExtension>(() => new TestGroupExtension());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestGroupExtension> _extensions;
+    private pb::ExtensionSet<TestGroupExtension> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestGroupExtension> Parser { get { return _parser; } }
 
@@ -8483,6 +8485,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestEmptyMessageWithExtensions> _parser = new pb::MessageParser<TestEmptyMessageWithExtensions>(() => new TestEmptyMessageWithExtensions());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestEmptyMessageWithExtensions> _extensions;
+    private pb::ExtensionSet<TestEmptyMessageWithExtensions> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestEmptyMessageWithExtensions> Parser { get { return _parser; } }
 
@@ -8623,6 +8626,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestMultipleExtensionRanges> _parser = new pb::MessageParser<TestMultipleExtensionRanges>(() => new TestMultipleExtensionRanges());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestMultipleExtensionRanges> _extensions;
+    private pb::ExtensionSet<TestMultipleExtensionRanges> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestMultipleExtensionRanges> Parser { get { return _parser; } }
 
@@ -11932,6 +11936,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestFieldOrderings> _parser = new pb::MessageParser<TestFieldOrderings>(() => new TestFieldOrderings());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestFieldOrderings> _extensions;
+    private pb::ExtensionSet<TestFieldOrderings> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestFieldOrderings> Parser { get { return _parser; } }
@@ -19245,6 +19250,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestPackedExtensions> _parser = new pb::MessageParser<TestPackedExtensions>(() => new TestPackedExtensions());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestPackedExtensions> _extensions;
+    private pb::ExtensionSet<TestPackedExtensions> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestPackedExtensions> Parser { get { return _parser; } }
 
@@ -19385,6 +19391,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestUnpackedExtensions> _parser = new pb::MessageParser<TestUnpackedExtensions>(() => new TestUnpackedExtensions());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestUnpackedExtensions> _extensions;
+    private pb::ExtensionSet<TestUnpackedExtensions> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestUnpackedExtensions> Parser { get { return _parser; } }
 
@@ -20287,6 +20294,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestParsingMerge> _parser = new pb::MessageParser<TestParsingMerge>(() => new TestParsingMerge());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestParsingMerge> _extensions;
+    private pb::ExtensionSet<TestParsingMerge> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestParsingMerge> Parser { get { return _parser; } }
 
@@ -22563,6 +22571,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestHugeFieldNumbers> _parser = new pb::MessageParser<TestHugeFieldNumbers>(() => new TestHugeFieldNumbers());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestHugeFieldNumbers> _extensions;
+    private pb::ExtensionSet<TestHugeFieldNumbers> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestHugeFieldNumbers> Parser { get { return _parser; } }
@@ -23417,6 +23426,7 @@ namespace Google.Protobuf.TestProtos.Proto2 {
     private static readonly pb::MessageParser<TestExtensionInsideTable> _parser = new pb::MessageParser<TestExtensionInsideTable>(() => new TestExtensionInsideTable());
     private pb::UnknownFieldSet _unknownFields;
     private pb::ExtensionSet<TestExtensionInsideTable> _extensions;
+    private pb::ExtensionSet<TestExtensionInsideTable> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestExtensionInsideTable> Parser { get { return _parser; } }

+ 9 - 0
csharp/src/Google.Protobuf/Reflection/Descriptor.cs

@@ -1591,6 +1591,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<ExtensionRangeOptions> _parser = new pb::MessageParser<ExtensionRangeOptions>(() => new ExtensionRangeOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<ExtensionRangeOptions> _extensions;
+    private pb::ExtensionSet<ExtensionRangeOptions> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ExtensionRangeOptions> Parser { get { return _parser; } }
 
@@ -3819,6 +3820,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<FileOptions> _parser = new pb::MessageParser<FileOptions>(() => new FileOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<FileOptions> _extensions;
+    private pb::ExtensionSet<FileOptions> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<FileOptions> Parser { get { return _parser; } }
@@ -4916,6 +4918,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<MessageOptions> _parser = new pb::MessageParser<MessageOptions>(() => new MessageOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<MessageOptions> _extensions;
+    private pb::ExtensionSet<MessageOptions> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<MessageOptions> Parser { get { return _parser; } }
@@ -5299,6 +5302,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<FieldOptions> _parser = new pb::MessageParser<FieldOptions>(() => new FieldOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<FieldOptions> _extensions;
+    private pb::ExtensionSet<FieldOptions> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<FieldOptions> Parser { get { return _parser; } }
@@ -5805,6 +5809,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<OneofOptions> _parser = new pb::MessageParser<OneofOptions>(() => new OneofOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<OneofOptions> _extensions;
+    private pb::ExtensionSet<OneofOptions> _Extensions => _extensions;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<OneofOptions> Parser { get { return _parser; } }
 
@@ -5968,6 +5973,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<EnumOptions> _parser = new pb::MessageParser<EnumOptions>(() => new EnumOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<EnumOptions> _extensions;
+    private pb::ExtensionSet<EnumOptions> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<EnumOptions> Parser { get { return _parser; } }
@@ -6225,6 +6231,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<EnumValueOptions> _parser = new pb::MessageParser<EnumValueOptions>(() => new EnumValueOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<EnumValueOptions> _extensions;
+    private pb::ExtensionSet<EnumValueOptions> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<EnumValueOptions> Parser { get { return _parser; } }
@@ -6437,6 +6444,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<ServiceOptions> _parser = new pb::MessageParser<ServiceOptions>(() => new ServiceOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<ServiceOptions> _extensions;
+    private pb::ExtensionSet<ServiceOptions> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ServiceOptions> Parser { get { return _parser; } }
@@ -6649,6 +6657,7 @@ namespace Google.Protobuf.Reflection {
     private static readonly pb::MessageParser<MethodOptions> _parser = new pb::MessageParser<MethodOptions>(() => new MethodOptions());
     private pb::UnknownFieldSet _unknownFields;
     internal pb::ExtensionSet<MethodOptions> _extensions;
+    private pb::ExtensionSet<MethodOptions> _Extensions => _extensions;
     private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<MethodOptions> Parser { get { return _parser; } }

+ 7 - 2
csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs

@@ -312,14 +312,19 @@ namespace Google.Protobuf.Reflection
         {
             public Func<IMessage, bool> CreateIsInitializedCaller()
             {
-                var field = typeof(T1).GetTypeInfo().GetDeclaredField("_extensions");
+                var prop = typeof(T1).GetTypeInfo().GetDeclaredProperty("_Extensions");
+#if NET35
+                var getFunc = (Func<T1, ExtensionSet<T1>>)prop.GetGetMethod(true).CreateDelegate(typeof(Func<T1, ExtensionSet<T1>>));
+#else
+                var getFunc = (Func<T1, ExtensionSet<T1>>)prop.GetMethod.CreateDelegate(typeof(Func<T1, ExtensionSet<T1>>));
+#endif
                 var initializedFunc = (Func<ExtensionSet<T1>, bool>)
                     typeof(ExtensionSet<T1>)
                         .GetTypeInfo()
                         .GetDeclaredMethod("IsInitialized")
                         .CreateDelegate(typeof(Func<ExtensionSet<T1>, bool>));
                 return (m) => {
-                    var set = field.GetValue(m) as ExtensionSet<T1>;
+                    var set = getFunc((T1)m);
                     return set == null || initializedFunc(set);
                 };
             }

+ 2 - 0
src/google/protobuf/compiler/csharp/csharp_message.cc

@@ -149,6 +149,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
     } else {
       printer->Print(vars, "private pb::ExtensionSet<$class_name$> _extensions;\n");
     }
+
+    printer->Print(vars, "private pb::ExtensionSet<$class_name$> _Extensions => _extensions;\n"); // a read-only property for fast retrieval of the set in IsInitialized
   }
 
   for (int i = 0; i < has_bit_field_count_; i++) {