292 lines
8.8 KiB
C#
292 lines
8.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Google.Protobuf.Reflection
|
|
{
|
|
// Token: 0x02000056 RID: 86
|
|
internal sealed class DescriptorPool
|
|
{
|
|
// Token: 0x06000564 RID: 1380 RVA: 0x000133BC File Offset: 0x000115BC
|
|
internal DescriptorPool(FileDescriptor[] dependencyFiles)
|
|
{
|
|
this.dependencies = new HashSet<FileDescriptor>();
|
|
for (int i = 0; i < dependencyFiles.Length; i++)
|
|
{
|
|
this.dependencies.Add(dependencyFiles[i]);
|
|
this.ImportPublicDependencies(dependencyFiles[i]);
|
|
}
|
|
foreach (FileDescriptor fileDescriptor in dependencyFiles)
|
|
{
|
|
this.AddPackage(fileDescriptor.Package, fileDescriptor);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000565 RID: 1381 RVA: 0x00013444 File Offset: 0x00011644
|
|
private void ImportPublicDependencies(FileDescriptor file)
|
|
{
|
|
foreach (FileDescriptor fileDescriptor in file.PublicDependencies)
|
|
{
|
|
if (this.dependencies.Add(fileDescriptor))
|
|
{
|
|
this.ImportPublicDependencies(fileDescriptor);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000566 RID: 1382 RVA: 0x000134A0 File Offset: 0x000116A0
|
|
internal T FindSymbol<T>(string fullName) where T : class
|
|
{
|
|
IDescriptor descriptor;
|
|
this.descriptorsByName.TryGetValue(fullName, out descriptor);
|
|
T t = descriptor as T;
|
|
if (t != null)
|
|
{
|
|
return t;
|
|
}
|
|
foreach (FileDescriptor fileDescriptor in this.dependencies)
|
|
{
|
|
fileDescriptor.DescriptorPool.descriptorsByName.TryGetValue(fullName, out descriptor);
|
|
t = descriptor as T;
|
|
if (t != null)
|
|
{
|
|
return t;
|
|
}
|
|
}
|
|
return default(T);
|
|
}
|
|
|
|
// Token: 0x06000567 RID: 1383 RVA: 0x00013548 File Offset: 0x00011748
|
|
internal void AddPackage(string fullName, FileDescriptor file)
|
|
{
|
|
int num = fullName.LastIndexOf('.');
|
|
string text;
|
|
if (num != -1)
|
|
{
|
|
this.AddPackage(fullName.Substring(0, num), file);
|
|
text = fullName.Substring(num + 1);
|
|
}
|
|
else
|
|
{
|
|
text = fullName;
|
|
}
|
|
IDescriptor descriptor;
|
|
if (this.descriptorsByName.TryGetValue(fullName, out descriptor) && !(descriptor is PackageDescriptor))
|
|
{
|
|
throw new DescriptorValidationException(file, string.Concat(new string[]
|
|
{
|
|
"\"",
|
|
text,
|
|
"\" is already defined (as something other than a package) in file \"",
|
|
descriptor.File.Name,
|
|
"\"."
|
|
}));
|
|
}
|
|
this.descriptorsByName[fullName] = new PackageDescriptor(text, fullName, file);
|
|
}
|
|
|
|
// Token: 0x06000568 RID: 1384 RVA: 0x000135E8 File Offset: 0x000117E8
|
|
internal void AddSymbol(IDescriptor descriptor)
|
|
{
|
|
DescriptorPool.ValidateSymbolName(descriptor);
|
|
string fullName = descriptor.FullName;
|
|
IDescriptor descriptor2;
|
|
if (this.descriptorsByName.TryGetValue(fullName, out descriptor2))
|
|
{
|
|
int num = fullName.LastIndexOf('.');
|
|
string text;
|
|
if (descriptor.File == descriptor2.File)
|
|
{
|
|
if (num == -1)
|
|
{
|
|
text = "\"" + fullName + "\" is already defined.";
|
|
}
|
|
else
|
|
{
|
|
text = string.Concat(new string[]
|
|
{
|
|
"\"",
|
|
fullName.Substring(num + 1),
|
|
"\" is already defined in \"",
|
|
fullName.Substring(0, num),
|
|
"\"."
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
text = string.Concat(new string[]
|
|
{
|
|
"\"",
|
|
fullName,
|
|
"\" is already defined in file \"",
|
|
descriptor2.File.Name,
|
|
"\"."
|
|
});
|
|
}
|
|
throw new DescriptorValidationException(descriptor, text);
|
|
}
|
|
this.descriptorsByName[fullName] = descriptor;
|
|
}
|
|
|
|
// Token: 0x06000569 RID: 1385 RVA: 0x000136CC File Offset: 0x000118CC
|
|
private static void ValidateSymbolName(IDescriptor descriptor)
|
|
{
|
|
if (descriptor.Name == "")
|
|
{
|
|
throw new DescriptorValidationException(descriptor, "Missing name.");
|
|
}
|
|
if (!DescriptorPool.ValidationRegex.IsMatch(descriptor.Name))
|
|
{
|
|
throw new DescriptorValidationException(descriptor, "\"" + descriptor.Name + "\" is not a valid identifier.");
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600056A RID: 1386 RVA: 0x00013728 File Offset: 0x00011928
|
|
internal FieldDescriptor FindFieldByNumber(MessageDescriptor messageDescriptor, int number)
|
|
{
|
|
FieldDescriptor fieldDescriptor;
|
|
this.fieldsByNumber.TryGetValue(new DescriptorPool.DescriptorIntPair(messageDescriptor, number), out fieldDescriptor);
|
|
return fieldDescriptor;
|
|
}
|
|
|
|
// Token: 0x0600056B RID: 1387 RVA: 0x0001374C File Offset: 0x0001194C
|
|
internal EnumValueDescriptor FindEnumValueByNumber(EnumDescriptor enumDescriptor, int number)
|
|
{
|
|
EnumValueDescriptor enumValueDescriptor;
|
|
this.enumValuesByNumber.TryGetValue(new DescriptorPool.DescriptorIntPair(enumDescriptor, number), out enumValueDescriptor);
|
|
return enumValueDescriptor;
|
|
}
|
|
|
|
// Token: 0x0600056C RID: 1388 RVA: 0x00013770 File Offset: 0x00011970
|
|
internal void AddFieldByNumber(FieldDescriptor field)
|
|
{
|
|
DescriptorPool.DescriptorIntPair descriptorIntPair = new DescriptorPool.DescriptorIntPair(field.ContainingType, field.FieldNumber);
|
|
FieldDescriptor fieldDescriptor;
|
|
if (this.fieldsByNumber.TryGetValue(descriptorIntPair, out fieldDescriptor))
|
|
{
|
|
throw new DescriptorValidationException(field, string.Concat(new object[]
|
|
{
|
|
"Field number ",
|
|
field.FieldNumber,
|
|
"has already been used in \"",
|
|
field.ContainingType.FullName,
|
|
"\" by field \"",
|
|
fieldDescriptor.Name,
|
|
"\"."
|
|
}));
|
|
}
|
|
this.fieldsByNumber[descriptorIntPair] = field;
|
|
}
|
|
|
|
// Token: 0x0600056D RID: 1389 RVA: 0x00013804 File Offset: 0x00011A04
|
|
internal void AddEnumValueByNumber(EnumValueDescriptor enumValue)
|
|
{
|
|
DescriptorPool.DescriptorIntPair descriptorIntPair = new DescriptorPool.DescriptorIntPair(enumValue.EnumDescriptor, enumValue.Number);
|
|
if (!this.enumValuesByNumber.ContainsKey(descriptorIntPair))
|
|
{
|
|
this.enumValuesByNumber[descriptorIntPair] = enumValue;
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600056E RID: 1390 RVA: 0x00013840 File Offset: 0x00011A40
|
|
internal IDescriptor LookupSymbol(string name, IDescriptor relativeTo)
|
|
{
|
|
IDescriptor descriptor;
|
|
if (name.StartsWith("."))
|
|
{
|
|
descriptor = this.FindSymbol<IDescriptor>(name.Substring(1));
|
|
}
|
|
else
|
|
{
|
|
int num = name.IndexOf('.');
|
|
string text = ((num == -1) ? name : name.Substring(0, num));
|
|
StringBuilder stringBuilder = new StringBuilder(relativeTo.FullName);
|
|
for (;;)
|
|
{
|
|
int num2 = stringBuilder.ToString().LastIndexOf(".");
|
|
if (num2 == -1)
|
|
{
|
|
break;
|
|
}
|
|
stringBuilder.Length = num2 + 1;
|
|
stringBuilder.Append(text);
|
|
descriptor = this.FindSymbol<IDescriptor>(stringBuilder.ToString());
|
|
if (descriptor != null)
|
|
{
|
|
goto Block_4;
|
|
}
|
|
stringBuilder.Length = num2;
|
|
}
|
|
descriptor = this.FindSymbol<IDescriptor>(name);
|
|
goto IL_B7;
|
|
Block_4:
|
|
if (num != -1)
|
|
{
|
|
int num2;
|
|
stringBuilder.Length = num2 + 1;
|
|
stringBuilder.Append(name);
|
|
descriptor = this.FindSymbol<IDescriptor>(stringBuilder.ToString());
|
|
}
|
|
}
|
|
IL_B7:
|
|
if (descriptor == null)
|
|
{
|
|
throw new DescriptorValidationException(relativeTo, "\"" + name + "\" is not defined.");
|
|
}
|
|
return descriptor;
|
|
}
|
|
|
|
// Token: 0x04000209 RID: 521
|
|
private readonly IDictionary<string, IDescriptor> descriptorsByName = new Dictionary<string, IDescriptor>();
|
|
|
|
// Token: 0x0400020A RID: 522
|
|
private readonly IDictionary<DescriptorPool.DescriptorIntPair, FieldDescriptor> fieldsByNumber = new Dictionary<DescriptorPool.DescriptorIntPair, FieldDescriptor>();
|
|
|
|
// Token: 0x0400020B RID: 523
|
|
private readonly IDictionary<DescriptorPool.DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber = new Dictionary<DescriptorPool.DescriptorIntPair, EnumValueDescriptor>();
|
|
|
|
// Token: 0x0400020C RID: 524
|
|
private readonly HashSet<FileDescriptor> dependencies;
|
|
|
|
// Token: 0x0400020D RID: 525
|
|
private static readonly Regex ValidationRegex = new Regex("^[_A-Za-z][_A-Za-z0-9]*$", FrameworkPortability.CompiledRegexWhereAvailable);
|
|
|
|
// Token: 0x020000BD RID: 189
|
|
private struct DescriptorIntPair : IEquatable<DescriptorPool.DescriptorIntPair>
|
|
{
|
|
// Token: 0x06000761 RID: 1889 RVA: 0x00017616 File Offset: 0x00015816
|
|
internal DescriptorIntPair(IDescriptor descriptor, int number)
|
|
{
|
|
this.number = number;
|
|
this.descriptor = descriptor;
|
|
}
|
|
|
|
// Token: 0x06000762 RID: 1890 RVA: 0x00017626 File Offset: 0x00015826
|
|
public bool Equals(DescriptorPool.DescriptorIntPair other)
|
|
{
|
|
return this.descriptor == other.descriptor && this.number == other.number;
|
|
}
|
|
|
|
// Token: 0x06000763 RID: 1891 RVA: 0x00017646 File Offset: 0x00015846
|
|
public override bool Equals(object obj)
|
|
{
|
|
return obj is DescriptorPool.DescriptorIntPair && this.Equals((DescriptorPool.DescriptorIntPair)obj);
|
|
}
|
|
|
|
// Token: 0x06000764 RID: 1892 RVA: 0x0001765E File Offset: 0x0001585E
|
|
public override int GetHashCode()
|
|
{
|
|
return this.descriptor.GetHashCode() * 65535 + this.number;
|
|
}
|
|
|
|
// Token: 0x040002F1 RID: 753
|
|
private readonly int number;
|
|
|
|
// Token: 0x040002F2 RID: 754
|
|
private readonly IDescriptor descriptor;
|
|
}
|
|
}
|
|
}
|