Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.7 KiB
96 lines
3.7 KiB
using System; |
|
using Google.ProtocolBuffers.DescriptorProtos; |
|
using Google.ProtocolBuffers.Descriptors; |
|
|
|
namespace Google.ProtocolBuffers.ProtoGen { |
|
/// <summary> |
|
/// Generator for the class describing the .proto file in general, |
|
/// containing things like the message descriptor. |
|
/// </summary> |
|
internal sealed class UmbrellaClassGenerator : SourceGeneratorBase<FileDescriptor>, ISourceGenerator { |
|
|
|
internal UmbrellaClassGenerator(FileDescriptor descriptor) |
|
: base(descriptor) { |
|
} |
|
|
|
public void Generate(TextGenerator writer) { |
|
WriteIntroduction(writer); |
|
WriteDescriptor(writer); |
|
WriteChildren(writer, "Extensions", Descriptor.Extensions); |
|
writer.WriteLine("#region Static variables"); |
|
foreach (MessageDescriptor message in Descriptor.MessageTypes) { |
|
new MessageGenerator(message).GenerateStaticVariables(writer); |
|
} |
|
writer.WriteLine("#endregion"); |
|
// The class declaration either gets closed before or after the children are written. |
|
if (!DescriptorUtil.NestClasses(Descriptor)) { |
|
writer.Outdent(); |
|
writer.WriteLine("}"); |
|
} |
|
WriteChildren(writer, "Enums", Descriptor.EnumTypes); |
|
WriteChildren(writer, "Messages", Descriptor.MessageTypes); |
|
WriteChildren(writer, "Services", Descriptor.Services); |
|
if (DescriptorUtil.NestClasses(Descriptor)) { |
|
writer.Outdent(); |
|
writer.WriteLine("}"); |
|
} |
|
if (DescriptorUtil.GetNamespace(Descriptor) != "") { |
|
writer.Outdent(); |
|
writer.WriteLine("}"); |
|
} |
|
} |
|
|
|
private void WriteIntroduction(TextGenerator writer) { |
|
writer.WriteLine("// Generated by the protocol buffer compiler. DO NOT EDIT!"); |
|
writer.WriteLine(); |
|
Helpers.WriteNamespaces(writer); |
|
|
|
if (DescriptorUtil.GetNamespace(Descriptor) != "") { |
|
writer.WriteLine("namespace {0} {{", DescriptorUtil.GetNamespace(Descriptor)); |
|
writer.Indent(); |
|
writer.WriteLine(); |
|
} |
|
|
|
writer.WriteLine("{0} static partial class {1} {{", ClassAccessLevel, DescriptorUtil.GetUmbrellaClassName(Descriptor)); |
|
writer.WriteLine(); |
|
writer.Indent(); |
|
} |
|
|
|
private void WriteDescriptor(TextGenerator writer) { |
|
writer.WriteLine("#region Descriptor"); |
|
|
|
writer.WriteLine("public static pbd::FileDescriptor Descriptor {"); |
|
writer.WriteLine(" get { return descriptor; }"); |
|
writer.WriteLine("}"); |
|
writer.WriteLine("private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom("); |
|
writer.WriteLine(" global::System.Convert.FromBase64String("); |
|
writer.Indent(); |
|
writer.Indent(); |
|
|
|
// TODO(jonskeet): Consider a C#-escaping format here instead of just Base64. |
|
byte[] bytes = Descriptor.Proto.ToByteArray(); |
|
string base64 = Convert.ToBase64String(bytes); |
|
|
|
while (base64.Length > 60) { |
|
writer.WriteLine("\"{0}\" + ", base64.Substring(0, 60)); |
|
base64 = base64.Substring(60); |
|
} |
|
writer.WriteLine("\"{0}\"),", base64); |
|
|
|
writer.WriteLine("new pbd::FileDescriptor[] {"); |
|
foreach (FileDescriptor dependency in Descriptor.Dependencies) { |
|
// TODO(jonskeet): The normal code won't work for the bootstrapping descriptor, because we don't get unknown fields :( |
|
if (dependency.Package == "google.protobuf" && dependency.Name.EndsWith("descriptor.proto")) { |
|
writer.WriteLine(" global::" + typeof(DescriptorProtoFile).FullName + ".Descriptor, "); |
|
continue; |
|
} |
|
writer.WriteLine(" {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency)); |
|
} |
|
writer.WriteLine("});"); |
|
writer.Outdent(); |
|
writer.Outdent(); |
|
writer.WriteLine("#endregion"); |
|
writer.WriteLine(); |
|
} |
|
} |
|
}
|
|
|