// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: conformance/conformance.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021, 8981
#region Designer generated code

using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Conformance {

  /// <summary>Holder for reflection information generated from conformance/conformance.proto</summary>
  public static partial class ConformanceReflection {

    #region Descriptor
    /// <summary>File descriptor for conformance/conformance.proto</summary>
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static ConformanceReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "Ch1jb25mb3JtYW5jZS9jb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2Ui",
            "HQoKRmFpbHVyZVNldBIPCgdmYWlsdXJlGAEgAygJIuMCChJDb25mb3JtYW5j",
            "ZVJlcXVlc3QSGgoQcHJvdG9idWZfcGF5bG9hZBgBIAEoDEgAEhYKDGpzb25f",
            "cGF5bG9hZBgCIAEoCUgAEhYKDGpzcGJfcGF5bG9hZBgHIAEoCUgAEhYKDHRl",
            "eHRfcGF5bG9hZBgIIAEoCUgAEjgKF3JlcXVlc3RlZF9vdXRwdXRfZm9ybWF0",
            "GAMgASgOMhcuY29uZm9ybWFuY2UuV2lyZUZvcm1hdBIUCgxtZXNzYWdlX3R5",
            "cGUYBCABKAkSMAoNdGVzdF9jYXRlZ29yeRgFIAEoDjIZLmNvbmZvcm1hbmNl",
            "LlRlc3RDYXRlZ29yeRI+ChVqc3BiX2VuY29kaW5nX29wdGlvbnMYBiABKAsy",
            "Hy5jb25mb3JtYW5jZS5Kc3BiRW5jb2RpbmdDb25maWcSHAoUcHJpbnRfdW5r",
            "bm93bl9maWVsZHMYCSABKAhCCQoHcGF5bG9hZCL6AQoTQ29uZm9ybWFuY2VS",
            "ZXNwb25zZRIVCgtwYXJzZV9lcnJvchgBIAEoCUgAEhkKD3NlcmlhbGl6ZV9l",
            "cnJvchgGIAEoCUgAEhcKDXRpbWVvdXRfZXJyb3IYCSABKAlIABIXCg1ydW50",
            "aW1lX2Vycm9yGAIgASgJSAASGgoQcHJvdG9idWZfcGF5bG9hZBgDIAEoDEgA",
            "EhYKDGpzb25fcGF5bG9hZBgEIAEoCUgAEhEKB3NraXBwZWQYBSABKAlIABIW",
            "Cgxqc3BiX3BheWxvYWQYByABKAlIABIWCgx0ZXh0X3BheWxvYWQYCCABKAlI",
            "AEIICgZyZXN1bHQiNwoSSnNwYkVuY29kaW5nQ29uZmlnEiEKGXVzZV9qc3Bi",
            "X2FycmF5X2FueV9mb3JtYXQYASABKAgqUAoKV2lyZUZvcm1hdBIPCgtVTlNQ",
            "RUNJRklFRBAAEgwKCFBST1RPQlVGEAESCAoESlNPThACEggKBEpTUEIQAxIP",
            "CgtURVhUX0ZPUk1BVBAEKo8BCgxUZXN0Q2F0ZWdvcnkSFAoQVU5TUEVDSUZJ",
            "RURfVEVTVBAAEg8KC0JJTkFSWV9URVNUEAESDQoJSlNPTl9URVNUEAISJAog",
            "SlNPTl9JR05PUkVfVU5LTk9XTl9QQVJTSU5HX1RFU1QQAxINCglKU1BCX1RF",
            "U1QQBBIUChBURVhUX0ZPUk1BVF9URVNUEAVCLwofY29tLmdvb2dsZS5wcm90",
            "b2J1Zi5jb25mb3JtYW5jZaICC0NvbmZvcm1hbmNlYgZwcm90bzM="));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.TestCategory), }, null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.FailureSet), global::Conformance.FailureSet.Parser, new[]{ "Failure" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "JspbPayload", "TextPayload", "RequestedOutputFormat", "MessageType", "TestCategory", "JspbEncodingOptions", "PrintUnknownFields" }, new[]{ "Payload" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "SerializeError", "TimeoutError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped", "JspbPayload", "TextPayload" }, new[]{ "Result" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.JspbEncodingConfig), global::Conformance.JspbEncodingConfig.Parser, new[]{ "UseJspbArrayAnyFormat" }, null, null, null, null)
          }));
    }
    #endregion

  }
  #region Enums
  public enum WireFormat {
    [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
    [pbr::OriginalName("PROTOBUF")] Protobuf = 1,
    [pbr::OriginalName("JSON")] Json = 2,
    /// <summary>
    /// Only used inside Google. Opensource testees just skip it.
    /// </summary>
    [pbr::OriginalName("JSPB")] Jspb = 3,
    [pbr::OriginalName("TEXT_FORMAT")] TextFormat = 4,
  }

  public enum TestCategory {
    [pbr::OriginalName("UNSPECIFIED_TEST")] UnspecifiedTest = 0,
    /// <summary>
    /// Test binary wire format.
    /// </summary>
    [pbr::OriginalName("BINARY_TEST")] BinaryTest = 1,
    /// <summary>
    /// Test json wire format.
    /// </summary>
    [pbr::OriginalName("JSON_TEST")] JsonTest = 2,
    /// <summary>
    /// Similar to JSON_TEST. However, during parsing json, testee should ignore
    /// unknown fields. This feature is optional. Each implementation can decide
    /// whether to support it.  See
    /// https://developers.google.com/protocol-buffers/docs/proto3#json_options
    /// for more detail.
    /// </summary>
    [pbr::OriginalName("JSON_IGNORE_UNKNOWN_PARSING_TEST")] JsonIgnoreUnknownParsingTest = 3,
    /// <summary>
    /// Test jspb wire format. Only used inside Google. Opensource testees just
    /// skip it.
    /// </summary>
    [pbr::OriginalName("JSPB_TEST")] JspbTest = 4,
    /// <summary>
    /// Test text format. For cpp, java and python, testees can already deal with
    /// this type. Testees of other languages can simply skip it.
    /// </summary>
    [pbr::OriginalName("TEXT_FORMAT_TEST")] TextFormatTest = 5,
  }

  #endregion

  #region Messages
  /// <summary>
  /// The conformance runner will request a list of failures as the first request.
  /// This will be known by message_type == "conformance.FailureSet", a conformance
  /// test should return a serialized FailureSet in protobuf_payload.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FailureSet : pb::IMessage<FailureSet>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<FailureSet> _parser = new pb::MessageParser<FailureSet>(() => new FailureSet());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FailureSet> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FailureSet() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FailureSet(FailureSet other) : this() {
      failure_ = other.failure_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FailureSet Clone() {
      return new FailureSet(this);
    }

    /// <summary>Field number for the "failure" field.</summary>
    public const int FailureFieldNumber = 1;
    private static readonly pb::FieldCodec<string> _repeated_failure_codec
        = pb::FieldCodec.ForString(10);
    private readonly pbc::RepeatedField<string> failure_ = new pbc::RepeatedField<string>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<string> Failure {
      get { return failure_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FailureSet);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(FailureSet other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!failure_.Equals(other.failure_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= failure_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      failure_.WriteTo(output, _repeated_failure_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      failure_.WriteTo(ref output, _repeated_failure_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      size += failure_.CalculateSize(_repeated_failure_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(FailureSet other) {
      if (other == null) {
        return;
      }
      failure_.Add(other.failure_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            failure_.AddEntriesFrom(input, _repeated_failure_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            failure_.AddEntriesFrom(ref input, _repeated_failure_codec);
            break;
          }
        }
      }
    }
    #endif

  }

  /// <summary>
  /// Represents a single test case's input.  The testee should:
  ///
  ///   1. parse this proto (which should always succeed)
  ///   2. parse the protobuf or JSON payload in "payload" (which may fail)
  ///   3. if the parse succeeded, serialize the message in the requested format.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class ConformanceRequest : pb::IMessage<ConformanceRequest>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<ConformanceRequest> _parser = new pb::MessageParser<ConformanceRequest>(() => new ConformanceRequest());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<ConformanceRequest> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[1]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ConformanceRequest() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ConformanceRequest(ConformanceRequest other) : this() {
      requestedOutputFormat_ = other.requestedOutputFormat_;
      messageType_ = other.messageType_;
      testCategory_ = other.testCategory_;
      jspbEncodingOptions_ = other.jspbEncodingOptions_ != null ? other.jspbEncodingOptions_.Clone() : null;
      printUnknownFields_ = other.printUnknownFields_;
      switch (other.PayloadCase) {
        case PayloadOneofCase.ProtobufPayload:
          ProtobufPayload = other.ProtobufPayload;
          break;
        case PayloadOneofCase.JsonPayload:
          JsonPayload = other.JsonPayload;
          break;
        case PayloadOneofCase.JspbPayload:
          JspbPayload = other.JspbPayload;
          break;
        case PayloadOneofCase.TextPayload:
          TextPayload = other.TextPayload;
          break;
      }

      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ConformanceRequest Clone() {
      return new ConformanceRequest(this);
    }

    /// <summary>Field number for the "protobuf_payload" field.</summary>
    public const int ProtobufPayloadFieldNumber = 1;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pb::ByteString ProtobufPayload {
      get { return HasProtobufPayload ? (pb::ByteString) payload_ : pb::ByteString.Empty; }
      set {
        payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        payloadCase_ = PayloadOneofCase.ProtobufPayload;
      }
    }
    /// <summary>Gets whether the "protobuf_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasProtobufPayload {
      get { return payloadCase_ == PayloadOneofCase.ProtobufPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "protobuf_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearProtobufPayload() {
      if (HasProtobufPayload) {
        ClearPayload();
      }
    }

    /// <summary>Field number for the "json_payload" field.</summary>
    public const int JsonPayloadFieldNumber = 2;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string JsonPayload {
      get { return HasJsonPayload ? (string) payload_ : ""; }
      set {
        payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        payloadCase_ = PayloadOneofCase.JsonPayload;
      }
    }
    /// <summary>Gets whether the "json_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJsonPayload {
      get { return payloadCase_ == PayloadOneofCase.JsonPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "json_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearJsonPayload() {
      if (HasJsonPayload) {
        ClearPayload();
      }
    }

    /// <summary>Field number for the "jspb_payload" field.</summary>
    public const int JspbPayloadFieldNumber = 7;
    /// <summary>
    /// Only used inside Google.  Opensource testees just skip it.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string JspbPayload {
      get { return HasJspbPayload ? (string) payload_ : ""; }
      set {
        payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        payloadCase_ = PayloadOneofCase.JspbPayload;
      }
    }
    /// <summary>Gets whether the "jspb_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJspbPayload {
      get { return payloadCase_ == PayloadOneofCase.JspbPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "jspb_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearJspbPayload() {
      if (HasJspbPayload) {
        ClearPayload();
      }
    }

    /// <summary>Field number for the "text_payload" field.</summary>
    public const int TextPayloadFieldNumber = 8;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string TextPayload {
      get { return HasTextPayload ? (string) payload_ : ""; }
      set {
        payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        payloadCase_ = PayloadOneofCase.TextPayload;
      }
    }
    /// <summary>Gets whether the "text_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasTextPayload {
      get { return payloadCase_ == PayloadOneofCase.TextPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "text_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearTextPayload() {
      if (HasTextPayload) {
        ClearPayload();
      }
    }

    /// <summary>Field number for the "requested_output_format" field.</summary>
    public const int RequestedOutputFormatFieldNumber = 3;
    private global::Conformance.WireFormat requestedOutputFormat_ = global::Conformance.WireFormat.Unspecified;
    /// <summary>
    /// Which format should the testee serialize its message to?
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Conformance.WireFormat RequestedOutputFormat {
      get { return requestedOutputFormat_; }
      set {
        requestedOutputFormat_ = value;
      }
    }

    /// <summary>Field number for the "message_type" field.</summary>
    public const int MessageTypeFieldNumber = 4;
    private string messageType_ = "";
    /// <summary>
    /// The full name for the test message to use; for the moment, either:
    /// protobuf_test_messages.proto3.TestAllTypesProto3 or
    /// protobuf_test_messages.google.protobuf.TestAllTypesProto2.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string MessageType {
      get { return messageType_; }
      set {
        messageType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "test_category" field.</summary>
    public const int TestCategoryFieldNumber = 5;
    private global::Conformance.TestCategory testCategory_ = global::Conformance.TestCategory.UnspecifiedTest;
    /// <summary>
    /// Each test is given a specific test category. Some category may need
    /// specific support in testee programs. Refer to the definition of
    /// TestCategory for more information.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Conformance.TestCategory TestCategory {
      get { return testCategory_; }
      set {
        testCategory_ = value;
      }
    }

    /// <summary>Field number for the "jspb_encoding_options" field.</summary>
    public const int JspbEncodingOptionsFieldNumber = 6;
    private global::Conformance.JspbEncodingConfig jspbEncodingOptions_;
    /// <summary>
    /// Specify details for how to encode jspb.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Conformance.JspbEncodingConfig JspbEncodingOptions {
      get { return jspbEncodingOptions_; }
      set {
        jspbEncodingOptions_ = value;
      }
    }

    /// <summary>Field number for the "print_unknown_fields" field.</summary>
    public const int PrintUnknownFieldsFieldNumber = 9;
    private bool printUnknownFields_;
    /// <summary>
    /// This can be used in json and text format. If true, testee should print
    /// unknown fields instead of ignore. This feature is optional.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool PrintUnknownFields {
      get { return printUnknownFields_; }
      set {
        printUnknownFields_ = value;
      }
    }

    private object payload_;
    /// <summary>Enum of possible cases for the "payload" oneof.</summary>
    public enum PayloadOneofCase {
      None = 0,
      ProtobufPayload = 1,
      JsonPayload = 2,
      JspbPayload = 7,
      TextPayload = 8,
    }
    private PayloadOneofCase payloadCase_ = PayloadOneofCase.None;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public PayloadOneofCase PayloadCase {
      get { return payloadCase_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearPayload() {
      payloadCase_ = PayloadOneofCase.None;
      payload_ = null;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as ConformanceRequest);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(ConformanceRequest other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (ProtobufPayload != other.ProtobufPayload) return false;
      if (JsonPayload != other.JsonPayload) return false;
      if (JspbPayload != other.JspbPayload) return false;
      if (TextPayload != other.TextPayload) return false;
      if (RequestedOutputFormat != other.RequestedOutputFormat) return false;
      if (MessageType != other.MessageType) return false;
      if (TestCategory != other.TestCategory) return false;
      if (!object.Equals(JspbEncodingOptions, other.JspbEncodingOptions)) return false;
      if (PrintUnknownFields != other.PrintUnknownFields) return false;
      if (PayloadCase != other.PayloadCase) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasProtobufPayload) hash ^= ProtobufPayload.GetHashCode();
      if (HasJsonPayload) hash ^= JsonPayload.GetHashCode();
      if (HasJspbPayload) hash ^= JspbPayload.GetHashCode();
      if (HasTextPayload) hash ^= TextPayload.GetHashCode();
      if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) hash ^= RequestedOutputFormat.GetHashCode();
      if (MessageType.Length != 0) hash ^= MessageType.GetHashCode();
      if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) hash ^= TestCategory.GetHashCode();
      if (jspbEncodingOptions_ != null) hash ^= JspbEncodingOptions.GetHashCode();
      if (PrintUnknownFields != false) hash ^= PrintUnknownFields.GetHashCode();
      hash ^= (int) payloadCase_;
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasProtobufPayload) {
        output.WriteRawTag(10);
        output.WriteBytes(ProtobufPayload);
      }
      if (HasJsonPayload) {
        output.WriteRawTag(18);
        output.WriteString(JsonPayload);
      }
      if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) {
        output.WriteRawTag(24);
        output.WriteEnum((int) RequestedOutputFormat);
      }
      if (MessageType.Length != 0) {
        output.WriteRawTag(34);
        output.WriteString(MessageType);
      }
      if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) {
        output.WriteRawTag(40);
        output.WriteEnum((int) TestCategory);
      }
      if (jspbEncodingOptions_ != null) {
        output.WriteRawTag(50);
        output.WriteMessage(JspbEncodingOptions);
      }
      if (HasJspbPayload) {
        output.WriteRawTag(58);
        output.WriteString(JspbPayload);
      }
      if (HasTextPayload) {
        output.WriteRawTag(66);
        output.WriteString(TextPayload);
      }
      if (PrintUnknownFields != false) {
        output.WriteRawTag(72);
        output.WriteBool(PrintUnknownFields);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasProtobufPayload) {
        output.WriteRawTag(10);
        output.WriteBytes(ProtobufPayload);
      }
      if (HasJsonPayload) {
        output.WriteRawTag(18);
        output.WriteString(JsonPayload);
      }
      if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) {
        output.WriteRawTag(24);
        output.WriteEnum((int) RequestedOutputFormat);
      }
      if (MessageType.Length != 0) {
        output.WriteRawTag(34);
        output.WriteString(MessageType);
      }
      if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) {
        output.WriteRawTag(40);
        output.WriteEnum((int) TestCategory);
      }
      if (jspbEncodingOptions_ != null) {
        output.WriteRawTag(50);
        output.WriteMessage(JspbEncodingOptions);
      }
      if (HasJspbPayload) {
        output.WriteRawTag(58);
        output.WriteString(JspbPayload);
      }
      if (HasTextPayload) {
        output.WriteRawTag(66);
        output.WriteString(TextPayload);
      }
      if (PrintUnknownFields != false) {
        output.WriteRawTag(72);
        output.WriteBool(PrintUnknownFields);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (HasProtobufPayload) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(ProtobufPayload);
      }
      if (HasJsonPayload) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonPayload);
      }
      if (HasJspbPayload) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JspbPayload);
      }
      if (HasTextPayload) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(TextPayload);
      }
      if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) RequestedOutputFormat);
      }
      if (MessageType.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageType);
      }
      if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) TestCategory);
      }
      if (jspbEncodingOptions_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(JspbEncodingOptions);
      }
      if (PrintUnknownFields != false) {
        size += 1 + 1;
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(ConformanceRequest other) {
      if (other == null) {
        return;
      }
      if (other.RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) {
        RequestedOutputFormat = other.RequestedOutputFormat;
      }
      if (other.MessageType.Length != 0) {
        MessageType = other.MessageType;
      }
      if (other.TestCategory != global::Conformance.TestCategory.UnspecifiedTest) {
        TestCategory = other.TestCategory;
      }
      if (other.jspbEncodingOptions_ != null) {
        if (jspbEncodingOptions_ == null) {
          JspbEncodingOptions = new global::Conformance.JspbEncodingConfig();
        }
        JspbEncodingOptions.MergeFrom(other.JspbEncodingOptions);
      }
      if (other.PrintUnknownFields != false) {
        PrintUnknownFields = other.PrintUnknownFields;
      }
      switch (other.PayloadCase) {
        case PayloadOneofCase.ProtobufPayload:
          ProtobufPayload = other.ProtobufPayload;
          break;
        case PayloadOneofCase.JsonPayload:
          JsonPayload = other.JsonPayload;
          break;
        case PayloadOneofCase.JspbPayload:
          JspbPayload = other.JspbPayload;
          break;
        case PayloadOneofCase.TextPayload:
          TextPayload = other.TextPayload;
          break;
      }

      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            ProtobufPayload = input.ReadBytes();
            break;
          }
          case 18: {
            JsonPayload = input.ReadString();
            break;
          }
          case 24: {
            RequestedOutputFormat = (global::Conformance.WireFormat) input.ReadEnum();
            break;
          }
          case 34: {
            MessageType = input.ReadString();
            break;
          }
          case 40: {
            TestCategory = (global::Conformance.TestCategory) input.ReadEnum();
            break;
          }
          case 50: {
            if (jspbEncodingOptions_ == null) {
              JspbEncodingOptions = new global::Conformance.JspbEncodingConfig();
            }
            input.ReadMessage(JspbEncodingOptions);
            break;
          }
          case 58: {
            JspbPayload = input.ReadString();
            break;
          }
          case 66: {
            TextPayload = input.ReadString();
            break;
          }
          case 72: {
            PrintUnknownFields = input.ReadBool();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            ProtobufPayload = input.ReadBytes();
            break;
          }
          case 18: {
            JsonPayload = input.ReadString();
            break;
          }
          case 24: {
            RequestedOutputFormat = (global::Conformance.WireFormat) input.ReadEnum();
            break;
          }
          case 34: {
            MessageType = input.ReadString();
            break;
          }
          case 40: {
            TestCategory = (global::Conformance.TestCategory) input.ReadEnum();
            break;
          }
          case 50: {
            if (jspbEncodingOptions_ == null) {
              JspbEncodingOptions = new global::Conformance.JspbEncodingConfig();
            }
            input.ReadMessage(JspbEncodingOptions);
            break;
          }
          case 58: {
            JspbPayload = input.ReadString();
            break;
          }
          case 66: {
            TextPayload = input.ReadString();
            break;
          }
          case 72: {
            PrintUnknownFields = input.ReadBool();
            break;
          }
        }
      }
    }
    #endif

  }

  /// <summary>
  /// Represents a single test case's output.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class ConformanceResponse : pb::IMessage<ConformanceResponse>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<ConformanceResponse> _parser = new pb::MessageParser<ConformanceResponse>(() => new ConformanceResponse());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<ConformanceResponse> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[2]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ConformanceResponse() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ConformanceResponse(ConformanceResponse other) : this() {
      switch (other.ResultCase) {
        case ResultOneofCase.ParseError:
          ParseError = other.ParseError;
          break;
        case ResultOneofCase.SerializeError:
          SerializeError = other.SerializeError;
          break;
        case ResultOneofCase.TimeoutError:
          TimeoutError = other.TimeoutError;
          break;
        case ResultOneofCase.RuntimeError:
          RuntimeError = other.RuntimeError;
          break;
        case ResultOneofCase.ProtobufPayload:
          ProtobufPayload = other.ProtobufPayload;
          break;
        case ResultOneofCase.JsonPayload:
          JsonPayload = other.JsonPayload;
          break;
        case ResultOneofCase.Skipped:
          Skipped = other.Skipped;
          break;
        case ResultOneofCase.JspbPayload:
          JspbPayload = other.JspbPayload;
          break;
        case ResultOneofCase.TextPayload:
          TextPayload = other.TextPayload;
          break;
      }

      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ConformanceResponse Clone() {
      return new ConformanceResponse(this);
    }

    /// <summary>Field number for the "parse_error" field.</summary>
    public const int ParseErrorFieldNumber = 1;
    /// <summary>
    /// This string should be set to indicate parsing failed.  The string can
    /// provide more information about the parse error if it is available.
    ///
    /// Setting this string does not necessarily mean the testee failed the
    /// test.  Some of the test cases are intentionally invalid input.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string ParseError {
      get { return HasParseError ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.ParseError;
      }
    }
    /// <summary>Gets whether the "parse_error" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasParseError {
      get { return resultCase_ == ResultOneofCase.ParseError; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "parse_error" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearParseError() {
      if (HasParseError) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "serialize_error" field.</summary>
    public const int SerializeErrorFieldNumber = 6;
    /// <summary>
    /// If the input was successfully parsed but errors occurred when
    /// serializing it to the requested output format, set the error message in
    /// this field.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string SerializeError {
      get { return HasSerializeError ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.SerializeError;
      }
    }
    /// <summary>Gets whether the "serialize_error" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasSerializeError {
      get { return resultCase_ == ResultOneofCase.SerializeError; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "serialize_error" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearSerializeError() {
      if (HasSerializeError) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "timeout_error" field.</summary>
    public const int TimeoutErrorFieldNumber = 9;
    /// <summary>
    /// This should be set if the test program timed out.  The string should
    /// provide more information about what the child process was doing when it
    /// was killed.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string TimeoutError {
      get { return HasTimeoutError ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.TimeoutError;
      }
    }
    /// <summary>Gets whether the "timeout_error" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasTimeoutError {
      get { return resultCase_ == ResultOneofCase.TimeoutError; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "timeout_error" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearTimeoutError() {
      if (HasTimeoutError) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "runtime_error" field.</summary>
    public const int RuntimeErrorFieldNumber = 2;
    /// <summary>
    /// This should be set if some other error occurred.  This will always
    /// indicate that the test failed.  The string can provide more information
    /// about the failure.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string RuntimeError {
      get { return HasRuntimeError ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.RuntimeError;
      }
    }
    /// <summary>Gets whether the "runtime_error" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasRuntimeError {
      get { return resultCase_ == ResultOneofCase.RuntimeError; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "runtime_error" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearRuntimeError() {
      if (HasRuntimeError) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "protobuf_payload" field.</summary>
    public const int ProtobufPayloadFieldNumber = 3;
    /// <summary>
    /// If the input was successfully parsed and the requested output was
    /// protobuf, serialize it to protobuf and set it in this field.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pb::ByteString ProtobufPayload {
      get { return HasProtobufPayload ? (pb::ByteString) result_ : pb::ByteString.Empty; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.ProtobufPayload;
      }
    }
    /// <summary>Gets whether the "protobuf_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasProtobufPayload {
      get { return resultCase_ == ResultOneofCase.ProtobufPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "protobuf_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearProtobufPayload() {
      if (HasProtobufPayload) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "json_payload" field.</summary>
    public const int JsonPayloadFieldNumber = 4;
    /// <summary>
    /// If the input was successfully parsed and the requested output was JSON,
    /// serialize to JSON and set it in this field.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string JsonPayload {
      get { return HasJsonPayload ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.JsonPayload;
      }
    }
    /// <summary>Gets whether the "json_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJsonPayload {
      get { return resultCase_ == ResultOneofCase.JsonPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "json_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearJsonPayload() {
      if (HasJsonPayload) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "skipped" field.</summary>
    public const int SkippedFieldNumber = 5;
    /// <summary>
    /// For when the testee skipped the test, likely because a certain feature
    /// wasn't supported, like JSON input/output.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string Skipped {
      get { return HasSkipped ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.Skipped;
      }
    }
    /// <summary>Gets whether the "skipped" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasSkipped {
      get { return resultCase_ == ResultOneofCase.Skipped; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "skipped" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearSkipped() {
      if (HasSkipped) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "jspb_payload" field.</summary>
    public const int JspbPayloadFieldNumber = 7;
    /// <summary>
    /// If the input was successfully parsed and the requested output was JSPB,
    /// serialize to JSPB and set it in this field. JSPB is only used inside
    /// Google. Opensource testees can just skip it.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string JspbPayload {
      get { return HasJspbPayload ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.JspbPayload;
      }
    }
    /// <summary>Gets whether the "jspb_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJspbPayload {
      get { return resultCase_ == ResultOneofCase.JspbPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "jspb_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearJspbPayload() {
      if (HasJspbPayload) {
        ClearResult();
      }
    }

    /// <summary>Field number for the "text_payload" field.</summary>
    public const int TextPayloadFieldNumber = 8;
    /// <summary>
    /// If the input was successfully parsed and the requested output was
    /// TEXT_FORMAT, serialize to TEXT_FORMAT and set it in this field.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string TextPayload {
      get { return HasTextPayload ? (string) result_ : ""; }
      set {
        result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        resultCase_ = ResultOneofCase.TextPayload;
      }
    }
    /// <summary>Gets whether the "text_payload" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasTextPayload {
      get { return resultCase_ == ResultOneofCase.TextPayload; }
    }
    /// <summary> Clears the value of the oneof if it's currently set to "text_payload" </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearTextPayload() {
      if (HasTextPayload) {
        ClearResult();
      }
    }

    private object result_;
    /// <summary>Enum of possible cases for the "result" oneof.</summary>
    public enum ResultOneofCase {
      None = 0,
      ParseError = 1,
      SerializeError = 6,
      TimeoutError = 9,
      RuntimeError = 2,
      ProtobufPayload = 3,
      JsonPayload = 4,
      Skipped = 5,
      JspbPayload = 7,
      TextPayload = 8,
    }
    private ResultOneofCase resultCase_ = ResultOneofCase.None;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ResultOneofCase ResultCase {
      get { return resultCase_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearResult() {
      resultCase_ = ResultOneofCase.None;
      result_ = null;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as ConformanceResponse);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(ConformanceResponse other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (ParseError != other.ParseError) return false;
      if (SerializeError != other.SerializeError) return false;
      if (TimeoutError != other.TimeoutError) return false;
      if (RuntimeError != other.RuntimeError) return false;
      if (ProtobufPayload != other.ProtobufPayload) return false;
      if (JsonPayload != other.JsonPayload) return false;
      if (Skipped != other.Skipped) return false;
      if (JspbPayload != other.JspbPayload) return false;
      if (TextPayload != other.TextPayload) return false;
      if (ResultCase != other.ResultCase) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasParseError) hash ^= ParseError.GetHashCode();
      if (HasSerializeError) hash ^= SerializeError.GetHashCode();
      if (HasTimeoutError) hash ^= TimeoutError.GetHashCode();
      if (HasRuntimeError) hash ^= RuntimeError.GetHashCode();
      if (HasProtobufPayload) hash ^= ProtobufPayload.GetHashCode();
      if (HasJsonPayload) hash ^= JsonPayload.GetHashCode();
      if (HasSkipped) hash ^= Skipped.GetHashCode();
      if (HasJspbPayload) hash ^= JspbPayload.GetHashCode();
      if (HasTextPayload) hash ^= TextPayload.GetHashCode();
      hash ^= (int) resultCase_;
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasParseError) {
        output.WriteRawTag(10);
        output.WriteString(ParseError);
      }
      if (HasRuntimeError) {
        output.WriteRawTag(18);
        output.WriteString(RuntimeError);
      }
      if (HasProtobufPayload) {
        output.WriteRawTag(26);
        output.WriteBytes(ProtobufPayload);
      }
      if (HasJsonPayload) {
        output.WriteRawTag(34);
        output.WriteString(JsonPayload);
      }
      if (HasSkipped) {
        output.WriteRawTag(42);
        output.WriteString(Skipped);
      }
      if (HasSerializeError) {
        output.WriteRawTag(50);
        output.WriteString(SerializeError);
      }
      if (HasJspbPayload) {
        output.WriteRawTag(58);
        output.WriteString(JspbPayload);
      }
      if (HasTextPayload) {
        output.WriteRawTag(66);
        output.WriteString(TextPayload);
      }
      if (HasTimeoutError) {
        output.WriteRawTag(74);
        output.WriteString(TimeoutError);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasParseError) {
        output.WriteRawTag(10);
        output.WriteString(ParseError);
      }
      if (HasRuntimeError) {
        output.WriteRawTag(18);
        output.WriteString(RuntimeError);
      }
      if (HasProtobufPayload) {
        output.WriteRawTag(26);
        output.WriteBytes(ProtobufPayload);
      }
      if (HasJsonPayload) {
        output.WriteRawTag(34);
        output.WriteString(JsonPayload);
      }
      if (HasSkipped) {
        output.WriteRawTag(42);
        output.WriteString(Skipped);
      }
      if (HasSerializeError) {
        output.WriteRawTag(50);
        output.WriteString(SerializeError);
      }
      if (HasJspbPayload) {
        output.WriteRawTag(58);
        output.WriteString(JspbPayload);
      }
      if (HasTextPayload) {
        output.WriteRawTag(66);
        output.WriteString(TextPayload);
      }
      if (HasTimeoutError) {
        output.WriteRawTag(74);
        output.WriteString(TimeoutError);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (HasParseError) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(ParseError);
      }
      if (HasSerializeError) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(SerializeError);
      }
      if (HasTimeoutError) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(TimeoutError);
      }
      if (HasRuntimeError) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(RuntimeError);
      }
      if (HasProtobufPayload) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(ProtobufPayload);
      }
      if (HasJsonPayload) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonPayload);
      }
      if (HasSkipped) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Skipped);
      }
      if (HasJspbPayload) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JspbPayload);
      }
      if (HasTextPayload) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(TextPayload);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(ConformanceResponse other) {
      if (other == null) {
        return;
      }
      switch (other.ResultCase) {
        case ResultOneofCase.ParseError:
          ParseError = other.ParseError;
          break;
        case ResultOneofCase.SerializeError:
          SerializeError = other.SerializeError;
          break;
        case ResultOneofCase.TimeoutError:
          TimeoutError = other.TimeoutError;
          break;
        case ResultOneofCase.RuntimeError:
          RuntimeError = other.RuntimeError;
          break;
        case ResultOneofCase.ProtobufPayload:
          ProtobufPayload = other.ProtobufPayload;
          break;
        case ResultOneofCase.JsonPayload:
          JsonPayload = other.JsonPayload;
          break;
        case ResultOneofCase.Skipped:
          Skipped = other.Skipped;
          break;
        case ResultOneofCase.JspbPayload:
          JspbPayload = other.JspbPayload;
          break;
        case ResultOneofCase.TextPayload:
          TextPayload = other.TextPayload;
          break;
      }

      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            ParseError = input.ReadString();
            break;
          }
          case 18: {
            RuntimeError = input.ReadString();
            break;
          }
          case 26: {
            ProtobufPayload = input.ReadBytes();
            break;
          }
          case 34: {
            JsonPayload = input.ReadString();
            break;
          }
          case 42: {
            Skipped = input.ReadString();
            break;
          }
          case 50: {
            SerializeError = input.ReadString();
            break;
          }
          case 58: {
            JspbPayload = input.ReadString();
            break;
          }
          case 66: {
            TextPayload = input.ReadString();
            break;
          }
          case 74: {
            TimeoutError = input.ReadString();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            ParseError = input.ReadString();
            break;
          }
          case 18: {
            RuntimeError = input.ReadString();
            break;
          }
          case 26: {
            ProtobufPayload = input.ReadBytes();
            break;
          }
          case 34: {
            JsonPayload = input.ReadString();
            break;
          }
          case 42: {
            Skipped = input.ReadString();
            break;
          }
          case 50: {
            SerializeError = input.ReadString();
            break;
          }
          case 58: {
            JspbPayload = input.ReadString();
            break;
          }
          case 66: {
            TextPayload = input.ReadString();
            break;
          }
          case 74: {
            TimeoutError = input.ReadString();
            break;
          }
        }
      }
    }
    #endif

  }

  /// <summary>
  /// Encoding options for jspb format.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class JspbEncodingConfig : pb::IMessage<JspbEncodingConfig>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<JspbEncodingConfig> _parser = new pb::MessageParser<JspbEncodingConfig>(() => new JspbEncodingConfig());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<JspbEncodingConfig> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[3]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public JspbEncodingConfig() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public JspbEncodingConfig(JspbEncodingConfig other) : this() {
      useJspbArrayAnyFormat_ = other.useJspbArrayAnyFormat_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public JspbEncodingConfig Clone() {
      return new JspbEncodingConfig(this);
    }

    /// <summary>Field number for the "use_jspb_array_any_format" field.</summary>
    public const int UseJspbArrayAnyFormatFieldNumber = 1;
    private bool useJspbArrayAnyFormat_;
    /// <summary>
    /// Encode the value field of Any as jspb array if true, otherwise binary.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool UseJspbArrayAnyFormat {
      get { return useJspbArrayAnyFormat_; }
      set {
        useJspbArrayAnyFormat_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as JspbEncodingConfig);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(JspbEncodingConfig other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (UseJspbArrayAnyFormat != other.UseJspbArrayAnyFormat) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (UseJspbArrayAnyFormat != false) hash ^= UseJspbArrayAnyFormat.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (UseJspbArrayAnyFormat != false) {
        output.WriteRawTag(8);
        output.WriteBool(UseJspbArrayAnyFormat);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (UseJspbArrayAnyFormat != false) {
        output.WriteRawTag(8);
        output.WriteBool(UseJspbArrayAnyFormat);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (UseJspbArrayAnyFormat != false) {
        size += 1 + 1;
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(JspbEncodingConfig other) {
      if (other == null) {
        return;
      }
      if (other.UseJspbArrayAnyFormat != false) {
        UseJspbArrayAnyFormat = other.UseJspbArrayAnyFormat;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 8: {
            UseJspbArrayAnyFormat = input.ReadBool();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 8: {
            UseJspbArrayAnyFormat = input.ReadBool();
            break;
          }
        }
      }
    }
    #endif

  }

  #endregion

}

#endregion Designer generated code
