|
@@ -98,64 +98,65 @@ namespace Google.Protobuf.Reflection
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return dictionary;
|
|
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)
|
|
internal DescriptorDeclaration GetDeclaration(IDescriptor descriptor)
|
|
{
|
|
{
|
|
- declarations.Value.TryGetValue(descriptor, out var declaration);
|
|
|
|
|
|
+ DescriptorDeclaration declaration;
|
|
|
|
+ declarations.Value.TryGetValue(descriptor, out declaration);
|
|
return declaration;
|
|
return declaration;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -191,7 +192,8 @@ namespace Google.Protobuf.Reflection
|
|
throw new DescriptorValidationException(@this, "Invalid public dependency index.");
|
|
throw new DescriptorValidationException(@this, "Invalid public dependency index.");
|
|
}
|
|
}
|
|
string name = proto.Dependency[index];
|
|
string name = proto.Dependency[index];
|
|
- if (!nameToFileMap.TryGetValue(name, out var file))
|
|
|
|
|
|
+ FileDescriptor file;
|
|
|
|
+ if (!nameToFileMap.TryGetValue(name, out file))
|
|
{
|
|
{
|
|
if (!allowUnknownDependencies)
|
|
if (!allowUnknownDependencies)
|
|
{
|
|
{
|
|
@@ -414,7 +416,8 @@ namespace Google.Protobuf.Reflection
|
|
var dependencies = new List<FileDescriptor>();
|
|
var dependencies = new List<FileDescriptor>();
|
|
foreach (var dependencyName in proto.Dependency)
|
|
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}");
|
|
throw new ArgumentException($"Dependency missing: {dependencyName}");
|
|
}
|
|
}
|