diff --git a/csharp/src/Google.Protobuf/FieldMaskTree.cs b/csharp/src/Google.Protobuf/FieldMaskTree.cs
index 36c823bed..ff9e08877 100644
--- a/csharp/src/Google.Protobuf/FieldMaskTree.cs
+++ b/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
}
}
}
-}
\ No newline at end of file
+}
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index 8ea3818a4..e65d3969d 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -5,6 +5,7 @@
Copyright 2015, Google Inc.
Google Protocol Buffers
3.6.1
+ 6
Google Inc.
netstandard1.0;net45
true
diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
index 6d4520c0b..992b792ad 100644
--- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
@@ -98,64 +98,65 @@ namespace Google.Protobuf.Reflection
}
}
return dictionary;
+ }
- IDescriptor FindDescriptorForPath(IList path)
+ private IDescriptor FindDescriptorForPath(IList 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 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;
+ return null;
}
+ IReadOnlyList topLevelList = GetNestedDescriptorListForField(path[0]);
+ DescriptorBase current = GetDescriptorFromList(topLevelList, path[1]);
- DescriptorBase GetDescriptorFromList(IReadOnlyList list, int index)
+ for (int i = 2; current != null && i < path.Count; i += 2)
{
- // 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];
+ var list = current.GetNestedDescriptorListForField(path[i]);
+ current = GetDescriptorFromList(list, path[i + 1]);
}
+ return current;
+ }
- IReadOnlyList GetNestedDescriptorListForField(int fieldNumber)
+ private DescriptorBase GetDescriptorFromList(IReadOnlyList 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)
{
- switch (fieldNumber)
- {
- case FileDescriptorProto.ServiceFieldNumber:
- return (IReadOnlyList) Services;
- case FileDescriptorProto.MessageTypeFieldNumber:
- return (IReadOnlyList) MessageTypes;
- case FileDescriptorProto.EnumTypeFieldNumber:
- return (IReadOnlyList) EnumTypes;
- default:
- return 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];
+ }
+
+ private IReadOnlyList GetNestedDescriptorListForField(int fieldNumber)
+ {
+ switch (fieldNumber)
+ {
+ case FileDescriptorProto.ServiceFieldNumber:
+ return (IReadOnlyList) Services;
+ case FileDescriptorProto.MessageTypeFieldNumber:
+ return (IReadOnlyList) MessageTypes;
+ case FileDescriptorProto.EnumTypeFieldNumber:
+ return (IReadOnlyList) 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();
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}");
}
diff --git a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
index d541570fd..5872ee20d 100644
--- a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
+++ b/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 =
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
index a92519745..2f5172f1c 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
@@ -308,7 +308,7 @@ namespace Google.Protobuf.WellKnownTypes
/// true if the two timestamps refer to the same nanosecond
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));
}
///