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 pbd::FileDescriptor descriptor;");
            writer.WriteLine();
            writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
            writer.Indent();
            writer.WriteLine("byte[] descriptorData = 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.Outdent();
            writer.Outdent();
            writer.WriteLine(
                "pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {");
            writer.Indent();
            writer.WriteLine("descriptor = root;");
            foreach (MessageDescriptor message in Descriptor.MessageTypes)
            {
                new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
            }
            foreach (FieldDescriptor extension in Descriptor.Extensions)
            {
                new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
            }

            if (UsesExtensions(Descriptor.Proto))
            {
                // Must construct an ExtensionRegistry containing all possible extensions
                // and return it.
                writer.WriteLine("pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();");
                writer.WriteLine("RegisterAllExtensions(registry);");
                foreach (FileDescriptor dependency in Descriptor.Dependencies)
                {
                    writer.WriteLine("{0}.RegisterAllExtensions(registry);",
                                     DescriptorUtil.GetFullUmbrellaClassName(dependency));
                }
                writer.WriteLine("return registry;");
            }
            else
            {
                writer.WriteLine("return null;");
            }
            writer.Outdent();
            writer.WriteLine("};");

            // -----------------------------------------------------------------
            // Invoke internalBuildGeneratedFileFrom() to build the file.
            writer.WriteLine("pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,");
            writer.WriteLine("    new pbd::FileDescriptor[] {");
            foreach (FileDescriptor dependency in Descriptor.Dependencies)
            {
                writer.WriteLine("    {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency));
            }
            writer.WriteLine("    }, assigner);");
            writer.Outdent();
            writer.WriteLine("}");
            writer.WriteLine("#endregion");
            writer.WriteLine();
        }
        public void Generate(TextGenerator writer)
        {
            if (Descriptor.File.CSharpOptions.AddSerializable)
            {
                writer.WriteLine("[global::System.SerializableAttribute()]");
            }
            writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
            WriteGeneratedCodeAttributes(writer);
            writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message{3}<{1}, {1}.Builder> {{",
                             ClassAccessLevel, ClassName,
                             Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated",
                             RuntimeSuffix);
            writer.Indent();
            if (Descriptor.File.CSharpOptions.GeneratePrivateCtor)
            {
                writer.WriteLine("private {0}() {{ }}", ClassName);
            }
            // Must call MakeReadOnly() to make sure all lists are made read-only
            writer.WriteLine("private static readonly {0} defaultInstance = new {0}().MakeReadOnly();", ClassName);

            if (OptimizeSpeed)
            {
                writer.WriteLine("private static readonly string[] _{0}FieldNames = new string[] {{ {2}{1}{2} }};",
                                 NameHelpers.UnderscoresToCamelCase(ClassName), String.Join("\", \"", FieldNames),
                                 FieldNames.Length > 0 ? "\"" : "");
                List <string> tags = new List <string>();
                foreach (string name in FieldNames)
                {
                    tags.Add(WireFormat.MakeTag(Descriptor.FindFieldByName(name)).ToString());
                }

                writer.WriteLine("private static readonly uint[] _{0}FieldTags = new uint[] {{ {1} }};",
                                 NameHelpers.UnderscoresToCamelCase(ClassName), String.Join(", ", tags.ToArray()));
            }
            writer.WriteLine("public static {0} DefaultInstance {{", ClassName);
            writer.WriteLine("  get { return defaultInstance; }");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
            writer.WriteLine("  get { return DefaultInstance; }");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("protected override {0} ThisMessage {{", ClassName);
            writer.WriteLine("  get { return this; }");
            writer.WriteLine("}");
            writer.WriteLine();
            if (!UseLiteRuntime)
            {
                writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
                writer.WriteLine("  get {{ return {0}.internal__{1}__Descriptor; }}",
                                 DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
                                 GetUniqueFileScopeIdentifier(Descriptor));
                writer.WriteLine("}");
                writer.WriteLine();
                writer.WriteLine(
                    "protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{",
                    ClassName);
                writer.WriteLine("  get {{ return {0}.internal__{1}__FieldAccessorTable; }}",
                                 DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
                                 GetUniqueFileScopeIdentifier(Descriptor));
                writer.WriteLine("}");
                writer.WriteLine();
            }

            // Extensions don't need to go in an extra nested type
            WriteChildren(writer, null, Descriptor.Extensions);

            if (Descriptor.EnumTypes.Count + Descriptor.NestedTypes.Count > 0)
            {
                writer.WriteLine("#region Nested types");
                writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
                WriteGeneratedCodeAttributes(writer);
                writer.WriteLine("public static partial class Types {");
                writer.Indent();
                WriteChildren(writer, null, Descriptor.EnumTypes);
                WriteChildren(writer, null, Descriptor.NestedTypes);
                writer.Outdent();
                writer.WriteLine("}");
                writer.WriteLine("#endregion");
                writer.WriteLine();
            }

            foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
            {
                if (Descriptor.File.CSharpOptions.ClsCompliance && GetFieldConstantName(fieldDescriptor).StartsWith("_"))
                {
                    writer.WriteLine("[global::System.CLSCompliant(false)]");
                }

                // Rats: we lose the debug comment here :(
                writer.WriteLine("public const int {0} = {1};", GetFieldConstantName(fieldDescriptor),
                                 fieldDescriptor.FieldNumber);
                CreateFieldGenerator(fieldDescriptor).GenerateMembers(writer);
                writer.WriteLine();
            }

            if (OptimizeSpeed)
            {
                GenerateIsInitialized(writer);
                GenerateMessageSerializationMethods(writer);
            }
            if (UseLiteRuntime)
            {
                GenerateLiteRuntimeMethods(writer);
            }

            GenerateParseFromMethods(writer);
            GenerateBuilder(writer);

            // Force the static initialization code for the file to run, since it may
            // initialize static variables declared in this class.
            writer.WriteLine("static {0}() {{", ClassName);
            // We call object.ReferenceEquals() just to make it a valid statement on its own.
            // Another option would be GetType(), but that causes problems in DescriptorProtoFile,
            // where the bootstrapping is somewhat recursive - type initializers call
            // each other, effectively. We temporarily see Descriptor as null.
            writer.WriteLine("  object.ReferenceEquals({0}.Descriptor, null);",
                             DescriptorUtil.GetFullUmbrellaClassName(Descriptor));
            writer.WriteLine("}");

            writer.Outdent();
            writer.WriteLine("}");
            writer.WriteLine();
        }
Esempio n. 3
0
        public void Generate(TextGenerator writer)
        {
            writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message{3}<{1}, {1}.Builder> {{",
                             ClassAccessLevel, ClassName,
                             Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated",
                             RuntimeSuffix);
            writer.Indent();
            // Must call BuildPartial() to make sure all lists are made read-only
            writer.WriteLine("private static readonly {0} defaultInstance = new Builder().BuildPartial();", ClassName);
            writer.WriteLine("public static {0} DefaultInstance {{", ClassName);
            writer.WriteLine("  get { return defaultInstance; }");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
            writer.WriteLine("  get { return defaultInstance; }");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("protected override {0} ThisMessage {{", ClassName);
            writer.WriteLine("  get { return this; }");
            writer.WriteLine("}");
            writer.WriteLine();
            if (!UseLiteRuntime)
            {
                writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
                writer.WriteLine("  get {{ return {0}.internal__{1}__Descriptor; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
                                 GetUniqueFileScopeIdentifier(Descriptor));
                writer.WriteLine("}");
                writer.WriteLine();
                writer.WriteLine("protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{", ClassName);
                writer.WriteLine("  get {{ return {0}.internal__{1}__FieldAccessorTable; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
                                 GetUniqueFileScopeIdentifier(Descriptor));
                writer.WriteLine("}");
                writer.WriteLine();
            }

            // Extensions don't need to go in an extra nested type
            WriteChildren(writer, null, Descriptor.Extensions);

            if (Descriptor.EnumTypes.Count + Descriptor.NestedTypes.Count > 0)
            {
                writer.WriteLine("#region Nested types");
                writer.WriteLine("public static class Types {");
                writer.Indent();
                WriteChildren(writer, null, Descriptor.EnumTypes);
                WriteChildren(writer, null, Descriptor.NestedTypes);
                writer.Outdent();
                writer.WriteLine("}");
                writer.WriteLine("#endregion");
                writer.WriteLine();
            }

            foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
            {
                // Rats: we lose the debug comment here :(
                writer.WriteLine("public const int {0} = {1};", GetFieldConstantName(fieldDescriptor), fieldDescriptor.FieldNumber);
                SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateMembers(writer);
                writer.WriteLine();
            }

            if (OptimizeSpeed)
            {
                GenerateIsInitialized(writer);
                GenerateMessageSerializationMethods(writer);
            }
            if (UseLiteRuntime)
            {
                GenerateLiteRuntimeMethods(writer);
            }

            GenerateParseFromMethods(writer);
            GenerateBuilder(writer);

            // Force the static initialization code for the file to run, since it may
            // initialize static variables declared in this class.
            writer.WriteLine("static {0}() {{", ClassName);
            // We call object.ReferenceEquals() just to make it a valid statement on its own.
            // Another option would be GetType(), but that causes problems in DescriptorProtoFile,
            // where the bootstrapping is somewhat recursive - type initializers call
            // each other, effectively. We temporarily see Descriptor as null.
            writer.WriteLine("  object.ReferenceEquals({0}.Descriptor, null);", DescriptorUtil.GetFullUmbrellaClassName(Descriptor));
            writer.WriteLine("}");

            writer.Outdent();
            writer.WriteLine("}");
            writer.WriteLine();
        }
        public void Generate(TextGenerator writer)
        {
            writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message<{1}, {1}.Builder> {{",
                             ClassAccessLevel, ClassName, Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated");
            writer.Indent();
            // Must call BuildPartial() to make sure all lists are made read-only
            writer.WriteLine("private static readonly {0} defaultInstance = new Builder().BuildPartial();", ClassName);
            writer.WriteLine("public static {0} DefaultInstance {{", ClassName);
            writer.WriteLine("  get { return defaultInstance; }");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
            writer.WriteLine("  get { return defaultInstance; }");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("protected override {0} ThisMessage {{", ClassName);
            writer.WriteLine("  get { return this; }");
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
            writer.WriteLine("  get {{ return {0}.internal__{1}__Descriptor; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
                             GetUniqueFileScopeIdentifier(Descriptor));
            writer.WriteLine("}");
            writer.WriteLine();
            writer.WriteLine("protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{", ClassName);
            writer.WriteLine("  get {{ return {0}.internal__{1}__FieldAccessorTable; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
                             GetUniqueFileScopeIdentifier(Descriptor));
            writer.WriteLine("}");
            writer.WriteLine();

            // Extensions don't need to go in an extra nested type
            WriteChildren(writer, null, Descriptor.Extensions);

            if (Descriptor.EnumTypes.Count + Descriptor.NestedTypes.Count > 0)
            {
                writer.WriteLine("#region Nested types");
                writer.WriteLine("public static class Types {");
                writer.Indent();
                WriteChildren(writer, null, Descriptor.EnumTypes);
                WriteChildren(writer, null, Descriptor.NestedTypes);
                writer.Outdent();
                writer.WriteLine("}");
                writer.WriteLine("#endregion");
                writer.WriteLine();
            }

            foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
            {
                // Rats: we lose the debug comment here :(
                SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateMembers(writer);
                writer.WriteLine();
            }

            if (Descriptor.File.Options.OptimizeFor == FileOptions.Types.OptimizeMode.SPEED)
            {
                GenerateIsInitialized(writer);
                GenerateMessageSerializationMethods(writer);
            }

            GenerateParseFromMethods(writer);
            GenerateBuilder(writer);
        }