// Generated by protoc-gen-cs, Version=2.4.1.521, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.Compiler.PluginProto {

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public static partial class Plugin {

    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
    }
    #endregion
    #region Static variables
    internal static pbd::MessageDescriptor internal__static_google_protobuf_compiler_CodeGeneratorRequest__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorRequest, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorRequest.Builder> internal__static_google_protobuf_compiler_CodeGeneratorRequest__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_google_protobuf_compiler_CodeGeneratorResponse__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Builder> internal__static_google_protobuf_compiler_CodeGeneratorResponse__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_google_protobuf_compiler_CodeGeneratorResponse_File__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.Builder> internal__static_google_protobuf_compiler_CodeGeneratorResponse_File__FieldAccessorTable;
    #endregion
    #region Descriptor
    public static pbd::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbd::FileDescriptor descriptor;

    static Plugin() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "CiVnb29nbGUvcHJvdG9idWYvY29tcGlsZXIvcGx1Z2luLnByb3RvEhhnb29n",
            "bGUucHJvdG9idWYuY29tcGlsZXIaIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlw",
            "dG9yLnByb3RvIn0KFENvZGVHZW5lcmF0b3JSZXF1ZXN0EhgKEGZpbGVfdG9f",
            "Z2VuZXJhdGUYASADKAkSEQoJcGFyYW1ldGVyGAIgASgJEjgKCnByb3RvX2Zp",
            "bGUYDyADKAsyJC5nb29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90",
            "byKqAQoVQ29kZUdlbmVyYXRvclJlc3BvbnNlEg0KBWVycm9yGAEgASgJEkIK",
            "BGZpbGUYDyADKAsyNC5nb29nbGUucHJvdG9idWYuY29tcGlsZXIuQ29kZUdl",
            "bmVyYXRvclJlc3BvbnNlLkZpbGUaPgoERmlsZRIMCgRuYW1lGAEgASgJEhcK",
            "D2luc2VydGlvbl9wb2ludBgCIAEoCRIPCgdjb250ZW50GA8gASgJQiwKHGNv",
          "bS5nb29nbGUucHJvdG9idWYuY29tcGlsZXJCDFBsdWdpblByb3Rvcw=="));
      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
        descriptor = root;
        internal__static_google_protobuf_compiler_CodeGeneratorRequest__Descriptor = Descriptor.MessageTypes[0];
        internal__static_google_protobuf_compiler_CodeGeneratorRequest__FieldAccessorTable =
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorRequest, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorRequest.Builder>(internal__static_google_protobuf_compiler_CodeGeneratorRequest__Descriptor,
                new string[] { "FileToGenerate", "Parameter", "ProtoFile", });
        internal__static_google_protobuf_compiler_CodeGeneratorResponse__Descriptor = Descriptor.MessageTypes[1];
        internal__static_google_protobuf_compiler_CodeGeneratorResponse__FieldAccessorTable =
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Builder>(internal__static_google_protobuf_compiler_CodeGeneratorResponse__Descriptor,
                new string[] { "Error", "File", });
        internal__static_google_protobuf_compiler_CodeGeneratorResponse_File__Descriptor = internal__static_google_protobuf_compiler_CodeGeneratorResponse__Descriptor.NestedTypes[0];
        internal__static_google_protobuf_compiler_CodeGeneratorResponse_File__FieldAccessorTable =
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.Builder>(internal__static_google_protobuf_compiler_CodeGeneratorResponse_File__Descriptor,
                new string[] { "Name", "InsertionPoint", "Content", });
        return null;
      };
      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbd::FileDescriptor[] {
          global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor,
          }, assigner);
    }
    #endregion

  }
  #region Messages
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class CodeGeneratorRequest : pb::GeneratedMessage<CodeGeneratorRequest, CodeGeneratorRequest.Builder> {
    private CodeGeneratorRequest() { }
    private static readonly CodeGeneratorRequest defaultInstance = new CodeGeneratorRequest().MakeReadOnly();
    private static readonly string[] _codeGeneratorRequestFieldNames = new string[] { "file_to_generate", "parameter", "proto_file" };
    private static readonly uint[] _codeGeneratorRequestFieldTags = new uint[] { 10, 18, 122 };
    public static CodeGeneratorRequest DefaultInstance {
      get { return defaultInstance; }
    }

    public override CodeGeneratorRequest DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override CodeGeneratorRequest ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.internal__static_google_protobuf_compiler_CodeGeneratorRequest__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<CodeGeneratorRequest, CodeGeneratorRequest.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.internal__static_google_protobuf_compiler_CodeGeneratorRequest__FieldAccessorTable; }
    }

    public const int FileToGenerateFieldNumber = 1;
    private pbc::PopsicleList<string> fileToGenerate_ = new pbc::PopsicleList<string>();
    public scg::IList<string> FileToGenerateList {
      get { return pbc::Lists.AsReadOnly(fileToGenerate_); }
    }
    public int FileToGenerateCount {
      get { return fileToGenerate_.Count; }
    }
    public string GetFileToGenerate(int index) {
      return fileToGenerate_[index];
    }

    public const int ParameterFieldNumber = 2;
    private bool hasParameter;
    private string parameter_ = "";
    public bool HasParameter {
      get { return hasParameter; }
    }
    public string Parameter {
      get { return parameter_; }
    }

    public const int ProtoFileFieldNumber = 15;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> protoFile_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto>();
    public scg::IList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> ProtoFileList {
      get { return protoFile_; }
    }
    public int ProtoFileCount {
      get { return protoFile_.Count; }
    }
    public global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto GetProtoFile(int index) {
      return protoFile_[index];
    }

    public override bool IsInitialized {
      get {
        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in ProtoFileList) {
          if (!element.IsInitialized) return false;
        }
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      string[] field_names = _codeGeneratorRequestFieldNames;
      if (fileToGenerate_.Count > 0) {
        output.WriteStringArray(1, field_names[0], fileToGenerate_);
      }
      if (hasParameter) {
        output.WriteString(2, field_names[1], Parameter);
      }
      if (protoFile_.Count > 0) {
        output.WriteMessageArray(15, field_names[2], protoFile_);
      }
      UnknownFields.WriteTo(output);
    }

    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;

        size = 0;
        {
          int dataSize = 0;
          foreach (string element in FileToGenerateList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 1 * fileToGenerate_.Count;
        }
        if (hasParameter) {
          size += pb::CodedOutputStream.ComputeStringSize(2, Parameter);
        }
        foreach (global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto element in ProtoFileList) {
          size += pb::CodedOutputStream.ComputeMessageSize(15, element);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }

    public static CodeGeneratorRequest ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CodeGeneratorRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CodeGeneratorRequest ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CodeGeneratorRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CodeGeneratorRequest ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CodeGeneratorRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static CodeGeneratorRequest ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static CodeGeneratorRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static CodeGeneratorRequest ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CodeGeneratorRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private CodeGeneratorRequest MakeReadOnly() {
      fileToGenerate_.MakeReadOnly();
      protoFile_.MakeReadOnly();
      return this;
    }

    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(CodeGeneratorRequest prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<CodeGeneratorRequest, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(CodeGeneratorRequest cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private CodeGeneratorRequest result;

      private CodeGeneratorRequest PrepareBuilder() {
        if (resultIsReadOnly) {
          CodeGeneratorRequest original = result;
          result = new CodeGeneratorRequest();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override CodeGeneratorRequest MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }

      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }

      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          return new Builder().MergeFrom(result);
        }
      }

      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorRequest.Descriptor; }
      }

      public override CodeGeneratorRequest DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorRequest.DefaultInstance; }
      }

      public override CodeGeneratorRequest BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is CodeGeneratorRequest) {
          return MergeFrom((CodeGeneratorRequest) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(CodeGeneratorRequest other) {
        if (other == global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorRequest.DefaultInstance) return this;
        PrepareBuilder();
        if (other.fileToGenerate_.Count != 0) {
          result.fileToGenerate_.Add(other.fileToGenerate_);
        }
        if (other.HasParameter) {
          Parameter = other.Parameter;
        }
        if (other.protoFile_.Count != 0) {
          result.protoFile_.Add(other.protoFile_);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }

      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }

      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_codeGeneratorRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _codeGeneratorRequestFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              break;
            }
            case 10: {
              input.ReadStringArray(tag, field_name, result.fileToGenerate_);
              break;
            }
            case 18: {
              result.hasParameter = input.ReadString(ref result.parameter_);
              break;
            }
            case 122: {
              input.ReadMessageArray(tag, field_name, result.protoFile_, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.DefaultInstance, extensionRegistry);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public pbc::IPopsicleList<string> FileToGenerateList {
        get { return PrepareBuilder().fileToGenerate_; }
      }
      public int FileToGenerateCount {
        get { return result.FileToGenerateCount; }
      }
      public string GetFileToGenerate(int index) {
        return result.GetFileToGenerate(index);
      }
      public Builder SetFileToGenerate(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.fileToGenerate_[index] = value;
        return this;
      }
      public Builder AddFileToGenerate(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.fileToGenerate_.Add(value);
        return this;
      }
      public Builder AddRangeFileToGenerate(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.fileToGenerate_.Add(values);
        return this;
      }
      public Builder ClearFileToGenerate() {
        PrepareBuilder();
        result.fileToGenerate_.Clear();
        return this;
      }

      public bool HasParameter {
        get { return result.hasParameter; }
      }
      public string Parameter {
        get { return result.Parameter; }
        set { SetParameter(value); }
      }
      public Builder SetParameter(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasParameter = true;
        result.parameter_ = value;
        return this;
      }
      public Builder ClearParameter() {
        PrepareBuilder();
        result.hasParameter = false;
        result.parameter_ = "";
        return this;
      }

      public pbc::IPopsicleList<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> ProtoFileList {
        get { return PrepareBuilder().protoFile_; }
      }
      public int ProtoFileCount {
        get { return result.ProtoFileCount; }
      }
      public global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto GetProtoFile(int index) {
        return result.GetProtoFile(index);
      }
      public Builder SetProtoFile(int index, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.protoFile_[index] = value;
        return this;
      }
      public Builder SetProtoFile(int index, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.protoFile_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddProtoFile(global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.protoFile_.Add(value);
        return this;
      }
      public Builder AddProtoFile(global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.protoFile_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeProtoFile(scg::IEnumerable<global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto> values) {
        PrepareBuilder();
        result.protoFile_.Add(values);
        return this;
      }
      public Builder ClearProtoFile() {
        PrepareBuilder();
        result.protoFile_.Clear();
        return this;
      }
    }
    static CodeGeneratorRequest() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class CodeGeneratorResponse : pb::GeneratedMessage<CodeGeneratorResponse, CodeGeneratorResponse.Builder> {
    private CodeGeneratorResponse() { }
    private static readonly CodeGeneratorResponse defaultInstance = new CodeGeneratorResponse().MakeReadOnly();
    private static readonly string[] _codeGeneratorResponseFieldNames = new string[] { "error", "file" };
    private static readonly uint[] _codeGeneratorResponseFieldTags = new uint[] { 10, 122 };
    public static CodeGeneratorResponse DefaultInstance {
      get { return defaultInstance; }
    }

    public override CodeGeneratorResponse DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override CodeGeneratorResponse ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.internal__static_google_protobuf_compiler_CodeGeneratorResponse__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<CodeGeneratorResponse, CodeGeneratorResponse.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.internal__static_google_protobuf_compiler_CodeGeneratorResponse__FieldAccessorTable; }
    }

    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class File : pb::GeneratedMessage<File, File.Builder> {
        private File() { }
        private static readonly File defaultInstance = new File().MakeReadOnly();
        private static readonly string[] _fileFieldNames = new string[] { "content", "insertion_point", "name" };
        private static readonly uint[] _fileFieldTags = new uint[] { 122, 18, 10 };
        public static File DefaultInstance {
          get { return defaultInstance; }
        }

        public override File DefaultInstanceForType {
          get { return DefaultInstance; }
        }

        protected override File ThisMessage {
          get { return this; }
        }

        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.internal__static_google_protobuf_compiler_CodeGeneratorResponse_File__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<File, File.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.internal__static_google_protobuf_compiler_CodeGeneratorResponse_File__FieldAccessorTable; }
        }

        public const int NameFieldNumber = 1;
        private bool hasName;
        private string name_ = "";
        public bool HasName {
          get { return hasName; }
        }
        public string Name {
          get { return name_; }
        }

        public const int InsertionPointFieldNumber = 2;
        private bool hasInsertionPoint;
        private string insertionPoint_ = "";
        public bool HasInsertionPoint {
          get { return hasInsertionPoint; }
        }
        public string InsertionPoint {
          get { return insertionPoint_; }
        }

        public const int ContentFieldNumber = 15;
        private bool hasContent;
        private string content_ = "";
        public bool HasContent {
          get { return hasContent; }
        }
        public string Content {
          get { return content_; }
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          string[] field_names = _fileFieldNames;
          if (hasName) {
            output.WriteString(1, field_names[2], Name);
          }
          if (hasInsertionPoint) {
            output.WriteString(2, field_names[1], InsertionPoint);
          }
          if (hasContent) {
            output.WriteString(15, field_names[0], Content);
          }
          UnknownFields.WriteTo(output);
        }

        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;

            size = 0;
            if (hasName) {
              size += pb::CodedOutputStream.ComputeStringSize(1, Name);
            }
            if (hasInsertionPoint) {
              size += pb::CodedOutputStream.ComputeStringSize(2, InsertionPoint);
            }
            if (hasContent) {
              size += pb::CodedOutputStream.ComputeStringSize(15, Content);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }

        public static File ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static File ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static File ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static File ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static File ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static File ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static File ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static File ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static File ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static File ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private File MakeReadOnly() {
          return this;
        }

        public static Builder CreateBuilder() { return new Builder(); }
        public override Builder ToBuilder() { return CreateBuilder(this); }
        public override Builder CreateBuilderForType() { return new Builder(); }
        public static Builder CreateBuilder(File prototype) {
          return new Builder(prototype);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<File, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(File cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }

          private bool resultIsReadOnly;
          private File result;

          private File PrepareBuilder() {
            if (resultIsReadOnly) {
              File original = result;
              result = new File();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }

          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }

          protected override File MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }

          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }

          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              return new Builder().MergeFrom(result);
            }
          }

          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.Descriptor; }
          }

          public override File DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.DefaultInstance; }
          }

          public override File BuildPartial() {
            if (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }

          public override Builder MergeFrom(pb::IMessage other) {
            if (other is File) {
              return MergeFrom((File) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }

          public override Builder MergeFrom(File other) {
            if (other == global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasName) {
              Name = other.Name;
            }
            if (other.HasInsertionPoint) {
              InsertionPoint = other.InsertionPoint;
            }
            if (other.HasContent) {
              Content = other.Content;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }

          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }

          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_fileFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _fileFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                default: {
                  if (pb::WireFormat.IsEndGroupTag(tag)) {
                    if (unknownFields != null) {
                      this.UnknownFields = unknownFields.Build();
                    }
                    return this;
                  }
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  break;
                }
                case 10: {
                  result.hasName = input.ReadString(ref result.name_);
                  break;
                }
                case 18: {
                  result.hasInsertionPoint = input.ReadString(ref result.insertionPoint_);
                  break;
                }
                case 122: {
                  result.hasContent = input.ReadString(ref result.content_);
                  break;
                }
              }
            }

            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }


          public bool HasName {
            get { return result.hasName; }
          }
          public string Name {
            get { return result.Name; }
            set { SetName(value); }
          }
          public Builder SetName(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasName = true;
            result.name_ = value;
            return this;
          }
          public Builder ClearName() {
            PrepareBuilder();
            result.hasName = false;
            result.name_ = "";
            return this;
          }

          public bool HasInsertionPoint {
            get { return result.hasInsertionPoint; }
          }
          public string InsertionPoint {
            get { return result.InsertionPoint; }
            set { SetInsertionPoint(value); }
          }
          public Builder SetInsertionPoint(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasInsertionPoint = true;
            result.insertionPoint_ = value;
            return this;
          }
          public Builder ClearInsertionPoint() {
            PrepareBuilder();
            result.hasInsertionPoint = false;
            result.insertionPoint_ = "";
            return this;
          }

          public bool HasContent {
            get { return result.hasContent; }
          }
          public string Content {
            get { return result.Content; }
            set { SetContent(value); }
          }
          public Builder SetContent(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasContent = true;
            result.content_ = value;
            return this;
          }
          public Builder ClearContent() {
            PrepareBuilder();
            result.hasContent = false;
            result.content_ = "";
            return this;
          }
        }
        static File() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.Descriptor, null);
        }
      }

    }
    #endregion

    public const int ErrorFieldNumber = 1;
    private bool hasError;
    private string error_ = "";
    public bool HasError {
      get { return hasError; }
    }
    public string Error {
      get { return error_; }
    }

    public const int FileFieldNumber = 15;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File> file_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File>();
    public scg::IList<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File> FileList {
      get { return file_; }
    }
    public int FileCount {
      get { return file_.Count; }
    }
    public global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File GetFile(int index) {
      return file_[index];
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      string[] field_names = _codeGeneratorResponseFieldNames;
      if (hasError) {
        output.WriteString(1, field_names[0], Error);
      }
      if (file_.Count > 0) {
        output.WriteMessageArray(15, field_names[1], file_);
      }
      UnknownFields.WriteTo(output);
    }

    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;

        size = 0;
        if (hasError) {
          size += pb::CodedOutputStream.ComputeStringSize(1, Error);
        }
        foreach (global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File element in FileList) {
          size += pb::CodedOutputStream.ComputeMessageSize(15, element);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }

    public static CodeGeneratorResponse ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CodeGeneratorResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CodeGeneratorResponse ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CodeGeneratorResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CodeGeneratorResponse ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CodeGeneratorResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static CodeGeneratorResponse ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static CodeGeneratorResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static CodeGeneratorResponse ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CodeGeneratorResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private CodeGeneratorResponse MakeReadOnly() {
      file_.MakeReadOnly();
      return this;
    }

    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(CodeGeneratorResponse prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<CodeGeneratorResponse, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(CodeGeneratorResponse cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private CodeGeneratorResponse result;

      private CodeGeneratorResponse PrepareBuilder() {
        if (resultIsReadOnly) {
          CodeGeneratorResponse original = result;
          result = new CodeGeneratorResponse();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override CodeGeneratorResponse MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }

      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }

      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          return new Builder().MergeFrom(result);
        }
      }

      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Descriptor; }
      }

      public override CodeGeneratorResponse DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.DefaultInstance; }
      }

      public override CodeGeneratorResponse BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is CodeGeneratorResponse) {
          return MergeFrom((CodeGeneratorResponse) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(CodeGeneratorResponse other) {
        if (other == global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasError) {
          Error = other.Error;
        }
        if (other.file_.Count != 0) {
          result.file_.Add(other.file_);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }

      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }

      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_codeGeneratorResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _codeGeneratorResponseFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              break;
            }
            case 10: {
              result.hasError = input.ReadString(ref result.error_);
              break;
            }
            case 122: {
              input.ReadMessageArray(tag, field_name, result.file_, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.DefaultInstance, extensionRegistry);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasError {
        get { return result.hasError; }
      }
      public string Error {
        get { return result.Error; }
        set { SetError(value); }
      }
      public Builder SetError(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasError = true;
        result.error_ = value;
        return this;
      }
      public Builder ClearError() {
        PrepareBuilder();
        result.hasError = false;
        result.error_ = "";
        return this;
      }

      public pbc::IPopsicleList<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File> FileList {
        get { return PrepareBuilder().file_; }
      }
      public int FileCount {
        get { return result.FileCount; }
      }
      public global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File GetFile(int index) {
        return result.GetFile(index);
      }
      public Builder SetFile(int index, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.file_[index] = value;
        return this;
      }
      public Builder SetFile(int index, global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.file_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddFile(global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.file_.Add(value);
        return this;
      }
      public Builder AddFile(global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.file_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeFile(scg::IEnumerable<global::Google.ProtocolBuffers.Compiler.PluginProto.CodeGeneratorResponse.Types.File> values) {
        PrepareBuilder();
        result.file_.Add(values);
        return this;
      }
      public Builder ClearFile() {
        PrepareBuilder();
        result.file_.Clear();
        return this;
      }
    }
    static CodeGeneratorResponse() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.Compiler.PluginProto.Plugin.Descriptor, null);
    }
  }

  #endregion

}

#endregion Designer generated code
