Bläddra i källkod

Merge pull request #5445 from haon4/master

Make Protobuf compatible with C# 6
Hao Nguyen 6 år sedan
förälder
incheckning
52fee0e8f0

+ 3 - 2
csharp/src/Google.Protobuf/FieldMaskTree.cs

@@ -120,7 +120,8 @@ namespace Google.Protobuf
                     return this;
                 }
 
-                if (!node.Children.TryGetValue(part, out var childNode))
+                Node childNode;
+                if (!node.Children.TryGetValue(part, out childNode))
                 {
                     createNewBranch = true;
                     childNode = new Node();
@@ -361,4 +362,4 @@ namespace Google.Protobuf
             }
         }
     }
-}
+}

+ 1 - 0
csharp/src/Google.Protobuf/Google.Protobuf.csproj

@@ -5,6 +5,7 @@
     <Copyright>Copyright 2015, Google Inc.</Copyright>
     <AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
     <VersionPrefix>3.6.1</VersionPrefix>
+    <LangVersion>6</LangVersion>
     <Authors>Google Inc.</Authors>
     <TargetFrameworks>netstandard1.0;net45</TargetFrameworks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>

+ 49 - 46
csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs

@@ -98,64 +98,65 @@ namespace Google.Protobuf.Reflection
                 }
             }
             return dictionary;
+        }
 
-            IDescriptor FindDescriptorForPath(IList<int> path)
+        private IDescriptor FindDescriptorForPath(IList<int> path)
+        {
+            // All complete declarations have an even, non-empty path length
+            // (There can be an empty path for a descriptor declaration, but that can't have any comments,
+            // so we currently ignore it.)
+            if (path.Count == 0 || (path.Count & 1) != 0)
             {
-                // All complete declarations have an even, non-empty path length
-                // (There can be an empty path for a descriptor declaration, but that can't have any comments,
-                // so we currently ignore it.)
-                if (path.Count == 0 || (path.Count & 1) != 0)
-                {
-                    return null;
-                }
-                IReadOnlyList<DescriptorBase> topLevelList = GetNestedDescriptorListForField(path[0]);
-                DescriptorBase current = GetDescriptorFromList(topLevelList, path[1]);
+                return null;
+            }
+            IReadOnlyList<DescriptorBase> topLevelList = GetNestedDescriptorListForField(path[0]);
+            DescriptorBase current = GetDescriptorFromList(topLevelList, path[1]);
 
-                for (int i = 2; current != null && i < path.Count; i += 2)
-                {
-                    var list = current.GetNestedDescriptorListForField(path[i]);
-                    current = GetDescriptorFromList(list, path[i + 1]);
-                }
-                return current;
+            for (int i = 2; current != null && i < path.Count; i += 2)
+            {
+                var list = current.GetNestedDescriptorListForField(path[i]);
+                current = GetDescriptorFromList(list, path[i + 1]);
             }
+            return current;
+        }
 
-            DescriptorBase GetDescriptorFromList(IReadOnlyList<DescriptorBase> list, int index)
+        private DescriptorBase GetDescriptorFromList(IReadOnlyList<DescriptorBase> list, int index)
+        {
+            // This is fine: it may be a newer version of protobuf than we understand, with a new descriptor
+            // field.
+            if (list == null)
             {
-                // This is fine: it may be a newer version of protobuf than we understand, with a new descriptor
-                // field.
-                if (list == null)
-                {
-                    return null;
-                }
-                // We *could* return null to silently continue, but this is basically data corruption.
-                if (index < 0 || index >= list.Count)
-                {
-                    // We don't have much extra information to give at this point unfortunately. If this becomes a problem,
-                    // we can pass in the complete path and report that and the file name.
-                    throw new InvalidProtocolBufferException($"Invalid descriptor location path: index out of range");
-                }
-                return list[index];
+                return null;
+            }
+            // We *could* return null to silently continue, but this is basically data corruption.
+            if (index < 0 || index >= list.Count)
+            {
+                // We don't have much extra information to give at this point unfortunately. If this becomes a problem,
+                // we can pass in the complete path and report that and the file name.
+                throw new InvalidProtocolBufferException($"Invalid descriptor location path: index out of range");
             }
+            return list[index];
+        }
 
-            IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber)
+        private IReadOnlyList<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber)
+        {
+            switch (fieldNumber)
             {
-                switch (fieldNumber)
-                {
-                    case FileDescriptorProto.ServiceFieldNumber:
-                        return (IReadOnlyList<DescriptorBase>) Services;
-                    case FileDescriptorProto.MessageTypeFieldNumber:
-                        return (IReadOnlyList<DescriptorBase>) MessageTypes;
-                    case FileDescriptorProto.EnumTypeFieldNumber:
-                        return (IReadOnlyList<DescriptorBase>) EnumTypes;
-                    default:
-                        return null;
-                }
+                case FileDescriptorProto.ServiceFieldNumber:
+                    return (IReadOnlyList<DescriptorBase>) Services;
+                case FileDescriptorProto.MessageTypeFieldNumber:
+                    return (IReadOnlyList<DescriptorBase>) MessageTypes;
+                case FileDescriptorProto.EnumTypeFieldNumber:
+                    return (IReadOnlyList<DescriptorBase>) EnumTypes;
+                default:
+                    return null;
             }
         }
 
         internal DescriptorDeclaration GetDeclaration(IDescriptor descriptor)
         {
-            declarations.Value.TryGetValue(descriptor, out var declaration);
+            DescriptorDeclaration declaration;
+            declarations.Value.TryGetValue(descriptor, out declaration);
             return declaration;
         }
 
@@ -191,7 +192,8 @@ namespace Google.Protobuf.Reflection
                     throw new DescriptorValidationException(@this, "Invalid public dependency index.");
                 }
                 string name = proto.Dependency[index];
-                if (!nameToFileMap.TryGetValue(name, out var file))
+                FileDescriptor file;
+                if (!nameToFileMap.TryGetValue(name, out file))
                 {
                     if (!allowUnknownDependencies)
                     {
@@ -414,7 +416,8 @@ namespace Google.Protobuf.Reflection
                 var dependencies = new List<FileDescriptor>();
                 foreach (var dependencyName in proto.Dependency)
                 {
-                    if (!descriptorsByName.TryGetValue(dependencyName, out var dependency))
+                    FileDescriptor dependency;
+                    if (!descriptorsByName.TryGetValue(dependencyName, out dependency))
                     {
                         throw new ArgumentException($"Dependency missing: {dependencyName}");
                     }

+ 12 - 3
csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs

@@ -60,13 +60,22 @@ namespace Google.Protobuf.Reflection
             if (descriptor.File.Proto.Syntax == "proto2")
             {
                 MethodInfo hasMethod = property.DeclaringType.GetRuntimeProperty("Has" + property.Name).GetMethod;
-                hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod ?? throw new ArgumentException("Not all required properties/methods are available"));
+                if (hasMethod == null) {
+                  throw new ArgumentException("Not all required properties/methods are available");
+                }
+                hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod);
                 MethodInfo clearMethod = property.DeclaringType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes);
-                clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod ?? throw new ArgumentException("Not all required properties/methods are available"));
+                if (clearMethod == null) {
+                  throw new ArgumentException("Not all required properties/methods are available");
+                }
+                clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod);
             }
             else
             {
-                hasDelegate = (_) => throw new InvalidOperationException("HasValue is not implemented for proto3 fields"); var clrType = property.PropertyType;
+                hasDelegate = message => {
+                  throw new InvalidOperationException("HasValue is not implemented for proto3 fields");
+                };
+                var clrType = property.PropertyType;
 
                 // TODO: Validate that this is a reasonable single field? (Should be a value type, a message type, or string/ByteString.) 
                 object defaultValue =

+ 1 - 1
csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs

@@ -308,7 +308,7 @@ namespace Google.Protobuf.WellKnownTypes
         /// <returns>true if the two timestamps refer to the same nanosecond</returns>
         public static bool operator ==(Timestamp a, Timestamp b)
         {
-            return ReferenceEquals(a, b) || (a is null ? (b is null ? true : false) : a.Equals(b));
+            return ReferenceEquals(a, b) || (ReferenceEquals(a, null) ? (ReferenceEquals(b, null) ? true : false) : a.Equals(b));
         }
 
         /// <summary>