| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 | 
							- using System.Collections;
 
- using Google.ProtocolBuffers.Descriptors;
 
- using Google.ProtocolBuffers.DescriptorProtos;
 
- using System.Collections.Generic;
 
- using ExtensionRange = Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange;
 
- namespace Google.ProtocolBuffers.ProtoGen {
 
-   internal class MessageGenerator : SourceGeneratorBase<MessageDescriptor>, ISourceGenerator {
 
-     internal MessageGenerator(MessageDescriptor descriptor) : base(descriptor) {
 
-     }
 
-     private string ClassName {
 
-       get { return Descriptor.Name; }
 
-     }
 
-     private string FullClassName {
 
-       get { return DescriptorUtil.GetClassName(Descriptor); }
 
-     }
 
-     /// <summary>
 
-     /// Get an identifier that uniquely identifies this type within the file.
 
-     /// This is used to declare static variables related to this type at the
 
-     /// outermost file scope.
 
-     /// </summary>
 
-     static string GetUniqueFileScopeIdentifier(IDescriptor descriptor) {
 
-       return "static_" + descriptor.FullName.Replace(".", "_");
 
-     }
 
-     internal void GenerateStaticVariables(TextGenerator writer) {
 
-       // Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
 
-       // used in the construction of descriptors, we have a tricky bootstrapping
 
-       // problem.  To help control static initialization order, we make sure all
 
-       // descriptors and other static data that depends on them are members of
 
-       // the proto-descriptor class.  This way, they will be initialized in
 
-       // a deterministic order.
 
-       string identifier = GetUniqueFileScopeIdentifier(Descriptor);
 
-       // The descriptor for this type.
 
-       string access = Descriptor.File.Options.GetExtension(CSharpOptions.CSharpNestClasses) ? "private" : "internal";
 
-       writer.WriteLine("{0} static readonly pbd::MessageDescriptor internal__{1}__Descriptor", access, identifier);
 
-       if (Descriptor.ContainingType == null) {
 
-         writer.WriteLine("    = Descriptor.MessageTypes[{0}];", Descriptor.Index);
 
-       } else {
 
-         writer.WriteLine("    = internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
 
-       }
 
-       writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable",
 
-           access, FullClassName, identifier);
 
-       writer.WriteLine("    = new pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder>(internal__{1}__Descriptor,",
 
-           FullClassName, identifier);
 
-       writer.Print("        new string[] { ");
 
-       foreach (FieldDescriptor field in Descriptor.Fields) {
 
-         writer.Write("\"{0}\", ", Helpers.UnderscoresToPascalCase(DescriptorUtil.GetFieldName(field)));
 
-       }
 
-       writer.WriteLine("});");
 
-       // Generate static members for all nested types.
 
-       foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
 
-         new MessageGenerator(nestedMessage).GenerateStaticVariables(writer);
 
-       }
 
-     }
 
-     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.File),
 
-           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.File),
 
-           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);
 
-     }
 
-     private void GenerateMessageSerializationMethods(TextGenerator writer) {
 
-       List<FieldDescriptor> sortedFields = new List<FieldDescriptor>(Descriptor.Fields);
 
-       sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));
 
-       List<ExtensionRange> sortedExtensions = new List<ExtensionRange>(Descriptor.Proto.ExtensionRangeList);
 
-       sortedExtensions.Sort((r1, r2) => (r1.Start.CompareTo(r2.Start)));
 
-       writer.WriteLine("public override void WriteTo(pb::CodedOutputStream output) {");
 
-       writer.Indent();
 
-       if (Descriptor.Proto.ExtensionRangeList.Count > 0) {
 
-         writer.WriteLine("pb::ExtendableMessage<{0}, {0}.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);",
 
-           ClassName);
 
-       }
 
-       // Merge the fields and the extension ranges, both sorted by field number.
 
-       for (int i = 0, j = 0; i < Descriptor.Fields.Count || j < sortedExtensions.Count; ) {
 
-         if (i == Descriptor.Fields.Count) {
 
-           GenerateSerializeOneExtensionRange(writer, sortedExtensions[j++]);
 
-         } else if (j == sortedExtensions.Count) {
 
-           GenerateSerializeOneField(writer, sortedFields[i++]);
 
-         } else if (sortedFields[i].FieldNumber < sortedExtensions[j].Start) {
 
-           GenerateSerializeOneField(writer, sortedFields[i++]);
 
-         } else {
 
-           GenerateSerializeOneExtensionRange(writer, sortedExtensions[j++]);
 
-         }
 
-       }
 
-       if (Descriptor.Proto.Options.MessageSetWireFormat) {
 
-         writer.WriteLine("UnknownFields.WriteAsMessageSetTo(output);");
 
-       } else {
 
-         writer.WriteLine("UnknownFields.WriteTo(output);");
 
-       }
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       writer.WriteLine("private int memoizedSerializedSize = -1;");
 
-       writer.WriteLine("public override int SerializedSize {");
 
-       writer.Indent();
 
-       writer.WriteLine("get {");
 
-       writer.Indent();
 
-       writer.WriteLine("int size = memoizedSerializedSize;");
 
-       writer.WriteLine("if (size != -1) return size;");
 
-       writer.WriteLine();
 
-       writer.WriteLine("size = 0;");
 
-       foreach (FieldDescriptor field in Descriptor.Fields) {
 
-         SourceGenerators.CreateFieldGenerator(field).GenerateSerializedSizeCode(writer);
 
-       }
 
-       if (Descriptor.Proto.ExtensionRangeCount > 0) {
 
-         writer.WriteLine("size += ExtensionsSerializedSize;");
 
-       }
 
-       if (Descriptor.Options.MessageSetWireFormat) {
 
-         writer.WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;");
 
-       } else {
 
-         writer.WriteLine("size += UnknownFields.SerializedSize;");
 
-       }
 
-       writer.WriteLine("memoizedSerializedSize = size;");
 
-       writer.WriteLine("return size;");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-     }
 
-     private static void GenerateSerializeOneField(TextGenerator writer, FieldDescriptor fieldDescriptor) {
 
-       SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateSerializationCode(writer);
 
-     }
 
-     private static void GenerateSerializeOneExtensionRange(TextGenerator writer, ExtensionRange extensionRange) {
 
-       writer.WriteLine("extensionWriter.WriteUntil({0}, output);", extensionRange.End);
 
-     }
 
-     private void GenerateParseFromMethods(TextGenerator writer) {
 
-       // Note:  These are separate from GenerateMessageSerializationMethods()
 
-       //   because they need to be generated even for messages that are optimized
 
-       //   for code size.
 
-       writer.WriteLine("public static {0} ParseFrom(pb::ByteString data) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("public static {0} ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("public static {0} ParseFrom(byte[] data) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("public static {0} ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("public static {0} ParseFrom(global::System.IO.Stream input) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("public static {0} ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("public static {0} ParseFrom(pb::CodedInputStream input) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("public static {0} ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
 
-       writer.WriteLine("  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
 
-       writer.WriteLine("}");
 
-     }
 
-     /// <summary>
 
-     /// Returns whether or not the specified message type has any required fields.
 
-     /// If it doesn't, calls to check for initialization can be optimised.
 
-     /// TODO(jonskeet): Move this into MessageDescriptor?
 
-     /// </summary>
 
-     private static bool HasRequiredFields(MessageDescriptor descriptor, Dictionary<MessageDescriptor,object> alreadySeen) {
 
-       if (alreadySeen.ContainsKey(descriptor)) {
 
-         // The type is already in cache.  This means that either:
 
-         // a. The type has no required fields.
 
-         // b. We are in the midst of checking if the type has required fields,
 
-         //    somewhere up the stack.  In this case, we know that if the type
 
-         //    has any required fields, they'll be found when we return to it,
 
-         //    and the whole call to HasRequiredFields() will return true.
 
-         //    Therefore, we don't have to check if this type has required fields
 
-         //    here.
 
-         return false;
 
-       }
 
-       alreadySeen[descriptor] = descriptor; // Value is irrelevant
 
-       // If the type has extensions, an extension with message type could contain
 
-       // required fields, so we have to be conservative and assume such an
 
-       // extension exists.
 
-       if (descriptor.Extensions.Count > 0) {
 
-         return true;
 
-       }
 
-       foreach (FieldDescriptor field in descriptor.Fields) {
 
-         if (field.IsRequired) {
 
-           return true;
 
-         }
 
-         // Message or group
 
-         if (field.MappedType == MappedType.Message) {
 
-           if (HasRequiredFields(field.MessageType, alreadySeen)) {
 
-             return true;
 
-           }
 
-         }
 
-       }
 
-       return false;
 
-     }
 
-     private void GenerateBuilder(TextGenerator writer) {
 
-       writer.WriteLine("public static Builder CreateBuilder() { return new Builder(); }");
 
-       writer.WriteLine("public override Builder CreateBuilderForType() { return new Builder(); }");
 
-       writer.WriteLine("public static Builder CreateBuilder({0} prototype) {{", ClassName);
 
-       writer.WriteLine("  return (Builder) new Builder().MergeFrom(prototype);");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       writer.WriteLine("{0} sealed partial class Builder : pb::{2}Builder<{1}, Builder> {{",
 
-           ClassAccessLevel, ClassName, Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated");
 
-       writer.Indent();
 
-       writer.WriteLine("protected override Builder ThisBuilder {");
 
-       writer.WriteLine("  get { return this; }");
 
-       writer.WriteLine("}");
 
-       GenerateCommonBuilderMethods(writer);
 
-       if (Descriptor.File.Options.OptimizeFor == FileOptions.Types.OptimizeMode.SPEED) {
 
-         GenerateBuilderParsingMethods(writer);
 
-       }
 
-       foreach (FieldDescriptor field in Descriptor.Fields) {
 
-         writer.WriteLine();
 
-         // No field comment :(
 
-         SourceGenerators.CreateFieldGenerator(field).GenerateBuilderMembers(writer);
 
-       }
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-     }
 
-     private void GenerateCommonBuilderMethods(TextGenerator writer) {
 
-       writer.WriteLine("{0} Builder() {{}}", ClassAccessLevel);
 
-       writer.WriteLine();
 
-       writer.WriteLine("{0} result = new {0}();", ClassName);
 
-       writer.WriteLine();
 
-       writer.WriteLine("protected override {0} MessageBeingBuilt {{", ClassName);
 
-       writer.WriteLine("  get { return result; }");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       writer.WriteLine("public override Builder Clear() {");
 
-       writer.WriteLine("  result = new {0}();", ClassName);
 
-       writer.WriteLine("  return this;");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       writer.WriteLine("public override Builder Clone() {");
 
-       writer.WriteLine("  return new Builder().MergeFrom(result);");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       writer.WriteLine("public override pbd::MessageDescriptor DescriptorForType {");
 
-       writer.WriteLine("  get {{ return {0}.Descriptor; }}", ClassName);
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
 
-       writer.WriteLine("  get {{ return {0}.DefaultInstance; }}", ClassName);
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-     
 
-       writer.WriteLine("public override {0} BuildPartial() {{", ClassName);
 
-       writer.Indent();
 
-       foreach (FieldDescriptor field in Descriptor.Fields) {
 
-         SourceGenerators.CreateFieldGenerator(field).GenerateBuildingCode(writer);
 
-       }
 
-       writer.WriteLine("{0} returnMe = result;", ClassName);
 
-       writer.WriteLine("result = null;");
 
-       writer.WriteLine("return returnMe;");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       if (Descriptor.File.Options.OptimizeFor == FileOptions.Types.OptimizeMode.SPEED) {
 
-         writer.WriteLine("public override Builder MergeFrom(pb::IMessage other) {");
 
-         writer.WriteLine("  if (other is {0}) {{", ClassName);
 
-         writer.WriteLine("    return MergeFrom(({0}) other);", ClassName);
 
-         writer.WriteLine("  } else {");
 
-         writer.WriteLine("    base.MergeFrom(other);");
 
-         writer.WriteLine("    return this;");
 
-         writer.WriteLine("  }");
 
-         writer.WriteLine("}");
 
-         writer.WriteLine();
 
-         writer.WriteLine("public override Builder MergeFrom({0} other) {{", ClassName);
 
-         // Optimization:  If other is the default instance, we know none of its
 
-         // fields are set so we can skip the merge.
 
-         writer.Indent();
 
-         writer.WriteLine("if (other == {0}.DefaultInstance) return this;", ClassName);
 
-         foreach (FieldDescriptor field in Descriptor.Fields) {
 
-           SourceGenerators.CreateFieldGenerator(field).GenerateMergingCode(writer);
 
-         }
 
-         writer.WriteLine("this.MergeUnknownFields(other.UnknownFields);");
 
-         writer.WriteLine("return this;");
 
-         writer.Outdent();
 
-         writer.WriteLine("}");
 
-         writer.WriteLine();
 
-       }
 
-     }
 
-     private void GenerateBuilderParsingMethods(TextGenerator writer) {
 
-       List<FieldDescriptor> sortedFields = new List<FieldDescriptor>(Descriptor.Fields);
 
-       sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));
 
-       writer.WriteLine("public override Builder MergeFrom(pb::CodedInputStream input) {");
 
-       writer.WriteLine("  return MergeFrom(input, pb::ExtensionRegistry.Empty);");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-       writer.WriteLine("public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
 
-       writer.Indent();
 
-       writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
 
-       writer.WriteLine("while (true) {");
 
-       writer.Indent();
 
-       writer.WriteLine("uint tag = input.ReadTag();");
 
-       writer.WriteLine("switch (tag) {");
 
-       writer.Indent();
 
-       writer.WriteLine("case 0: {"); // 0 signals EOF / limit reached
 
-       writer.WriteLine("  this.UnknownFields = unknownFields.Build();");
 
-       writer.WriteLine("  return this;");
 
-       writer.WriteLine("}");
 
-       writer.WriteLine("default: {");
 
-       writer.WriteLine("  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {");
 
-       writer.WriteLine("    this.UnknownFields = unknownFields.Build();");
 
-       writer.WriteLine("    return this;"); // it's an endgroup tag
 
-       writer.WriteLine("  }");
 
-       writer.WriteLine("  break;");
 
-       writer.WriteLine("}");
 
-       foreach (FieldDescriptor field in sortedFields) {
 
-         uint tag = WireFormat.MakeTag(field.FieldNumber, WireFormat.GetWireType(field.FieldType));
 
-         writer.WriteLine("case {0}: {{", tag);
 
-         writer.Indent();
 
-         SourceGenerators.CreateFieldGenerator(field).GenerateParsingCode(writer);
 
-         writer.WriteLine("break;");
 
-         writer.Outdent();
 
-         writer.WriteLine("}");
 
-       }
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-     }
 
-     private void GenerateIsInitialized(TextGenerator writer) {
 
-       writer.WriteLine("public override bool IsInitialized {");
 
-       writer.Indent();
 
-       writer.WriteLine("get {");
 
-       writer.Indent();
 
-       // Check that all required fields in this message are set.
 
-       // TODO(kenton):  We can optimize this when we switch to putting all the
 
-       // "has" fields into a single bitfield.
 
-       foreach (FieldDescriptor field in Descriptor.Fields) {
 
-         if (field.IsRequired) {
 
-           writer.WriteLine("if (!has{0}) return false;", Helpers.UnderscoresToPascalCase(field.Name));
 
-         }
 
-       }
 
-   
 
-       // Now check that all embedded messages are initialized.
 
-       foreach (FieldDescriptor field in Descriptor.Fields) {
 
-         if (field.FieldType != FieldType.Message ||
 
-             !HasRequiredFields(field.MessageType, new Dictionary<MessageDescriptor, object>())) {
 
-           continue;
 
-         }
 
-         string propertyName = Helpers.UnderscoresToPascalCase(DescriptorUtil.GetFieldName(field));
 
-         if (field.IsRepeated) {
 
-           writer.WriteLine("foreach ({0} element in {1}List) {{", DescriptorUtil.GetClassName(field.MessageType), propertyName);
 
-           writer.WriteLine("  if (!element.IsInitialized) return false;");
 
-           writer.WriteLine("}");
 
-         } else if (field.IsOptional) {
 
-           writer.WriteLine("if (Has{0}) {{", propertyName);
 
-           writer.WriteLine("  if (!{0}.IsInitialized) return false;", propertyName);
 
-           writer.WriteLine("}");
 
-         } else {
 
-           writer.WriteLine("if (!{0}.IsInitialized) return false;", propertyName);
 
-         }
 
-       }
 
-       if (Descriptor.Extensions.Count > 0) {
 
-         writer.WriteLine("if (!ExtensionsAreInitialized) return false;");
 
-       }
 
-       writer.WriteLine("return true;");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.Outdent();
 
-       writer.WriteLine("}");
 
-       writer.WriteLine();
 
-     }
 
-   }
 
- }
 
 
  |