Merge pull request #5445 from haon4/master
Make Protobuf compatible with C# 6
This commit is contained in:
commit
52fee0e8f0
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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]);
|
||||
|
||||
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<DescriptorBase> topLevelList = GetNestedDescriptorListForField(path[0]);
|
||||
DescriptorBase current = GetDescriptorFromList(topLevelList, path[1]);
|
||||
|
||||
DescriptorBase GetDescriptorFromList(IReadOnlyList<DescriptorBase> 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<DescriptorBase> GetNestedDescriptorListForField(int fieldNumber)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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<DescriptorBase> GetNestedDescriptorListForField(int 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;
|
||||
}
|
||||
}
|
||||
|
||||
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}");
|
||||
}
|
||||
|
@ -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 =
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user