using System; using Google.ProtocolBuffers.DescriptorProtos; using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers.ProtoGen { /// /// Generator for the class describing the .proto file in general, /// containing things like the message descriptor. /// internal sealed class UmbrellaClassGenerator : SourceGeneratorBase, ISourceGenerator { internal UmbrellaClassGenerator(FileDescriptor descriptor) : base(descriptor) { } public string UmbrellaClassName { get { throw new NotImplementedException(); } } 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 (!Descriptor.CSharpOptions.NestClasses) { writer.Outdent(); writer.WriteLine("}"); } WriteChildren(writer, "Enums", Descriptor.EnumTypes); WriteChildren(writer, "Messages", Descriptor.MessageTypes); WriteChildren(writer, "Services", Descriptor.Services); if (Descriptor.CSharpOptions.NestClasses) { writer.Outdent(); writer.WriteLine("}"); } if (Descriptor.CSharpOptions.Namespace != "") { 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 (Descriptor.CSharpOptions.Namespace != "") { writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.Namespace); writer.Indent(); writer.WriteLine(); } writer.WriteLine("{0} static partial class {1} {{", ClassAccessLevel, Descriptor.CSharpOptions.UmbrellaClassname); 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) { writer.WriteLine(" {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency)); } writer.WriteLine("});"); writer.Outdent(); writer.Outdent(); writer.WriteLine("#endregion"); writer.WriteLine(); } } }