// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: csharp/protos/nrt.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 Google.Protobuf.TestProtos {

  #nullable enable annotations
  /// <summary>Holder for reflection information generated from csharp/protos/nrt.proto</summary>
  public static partial class NrtReflection {

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

    static NrtReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "Chdjc2hhcnAvcHJvdG9zL25ydC5wcm90bxIYcHJvdG9idWZfZWRpdGlvbnN0",
            "ZXN0aW5nGipjc2hhcnAvcHJvdG9zL3VuaXR0ZXN0X2ltcG9ydF9wcm90bzMu",
            "cHJvdG8aHGNzaGFycC9wcm90b3MvdW5pdHRlc3QucHJvdG8imQIKCk5ydE1l",
            "c3NhZ2USRgoVcHJvdG8zX2ltcG9ydF9tZXNzYWdlGAEgASgLMicucHJvdG9i",
            "dWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2USQAoNb3RoZXJfbWVz",
            "c2FnZRgCIAEoCzIpLnByb3RvYnVmX2VkaXRpb25zdGVzdGluZy5PdGhlck5y",
            "dE1lc3NhZ2USDAoEdGV4dBgDIAEoCRIPCgdpbnRlZ2VyGAQgASgFEgwKBGJs",
            "b2IYBSABKAwSNQoKZW51bV9maWVsZBgGIAEoDjIhLnByb3RvYnVmX2VkaXRp",
            "b25zdGVzdGluZy5OcnRFbnVtGh0KDU5lc3RlZE1lc3NhZ2USDAoEdGV4dBgB",
            "IAEoCSIfCg9PdGhlck5ydE1lc3NhZ2USDAoEdGV4dBgBIAEoCSIiChRFeHRl",
            "bmRhYmxlTnJ0TWVzc2FnZSoKCICABBCAgICAAio1CgdOcnRFbnVtEhgKFE5S",
            "VF9FTlVNX1VOU1BFQ0lGSUVEEAASBwoDRk9PEAESBwoDQkFSEAI6QAoJaW50",
            "MzJfZXh0EisucHJvdG9idWZfdW5pdHRlc3RfcHJvdG8yLlRlc3RBbGxFeHRl",
            "bnNpb25zGIetSyABKAU6QQoKc3RyaW5nX2V4dBIrLnByb3RvYnVmX3VuaXR0",
            "ZXN0X3Byb3RvMi5UZXN0QWxsRXh0ZW5zaW9ucxiIrUsgASgJOm8KC21lc3Nh",
            "Z2VfZXh0EisucHJvdG9idWZfdW5pdHRlc3RfcHJvdG8yLlRlc3RBbGxFeHRl",
            "bnNpb25zGImtSyABKAsyKy5wcm90b2J1Zl91bml0dGVzdF9wcm90bzIuVGVz",
            "dEFsbEV4dGVuc2lvbnNCJaoCGkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9z",
            "kgMF4j4CCAFiCGVkaXRpb25zcOoHei1jc2hhcnAvZ29vZ2xlL3Byb3RvYnVm",
            "L2Nfc2hhcnBfZmVhdHVyZXMucHJvdG8="));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportProto3Reflection.Descriptor, global::Google.Protobuf.TestProtos.Proto2.UnittestReflection.Descriptor, },
          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.NrtEnum), }, new pb::Extension[] { NrtExtensions.Int32Ext, NrtExtensions.StringExt, NrtExtensions.MessageExt }, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.NrtMessage), global::Google.Protobuf.TestProtos.NrtMessage.Parser, new[]{ "Proto3ImportMessage", "OtherMessage", "Text", "Integer", "Blob", "EnumField" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.NrtMessage.Types.NestedMessage), global::Google.Protobuf.TestProtos.NrtMessage.Types.NestedMessage.Parser, new[]{ "Text" }, null, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OtherNrtMessage), global::Google.Protobuf.TestProtos.OtherNrtMessage.Parser, new[]{ "Text" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.ExtendableNrtMessage), global::Google.Protobuf.TestProtos.ExtendableNrtMessage.Parser, null, null, null, null, null)
          }));
    }
    #endregion

  }
  /// <summary>Holder for extension identifiers generated from the top level of csharp/protos/nrt.proto</summary>
  public static partial class NrtExtensions {
    public static readonly pb::Extension<global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions, int> Int32Ext =
      new pb::Extension<global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions, int>(1234567, pb::FieldCodec.ForInt32(9876536, 0));
    public static readonly pb::Extension<global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions, string> StringExt =
      new pb::Extension<global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions, string>(1234568, pb::FieldCodec.ForString(9876546, ""));
    public static readonly pb::Extension<global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions, global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions> MessageExt =
      new pb::Extension<global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions, global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions>(1234569, pb::FieldCodec.ForMessage(9876554, global::Google.Protobuf.TestProtos.Proto2.TestAllExtensions.Parser));
  }

  #region Enums
  public enum NrtEnum {
    [pbr::OriginalName("NRT_ENUM_UNSPECIFIED")] Unspecified = 0,
    [pbr::OriginalName("FOO")] Foo = 1,
    [pbr::OriginalName("BAR")] Bar = 2,
  }

  #endregion

  #region Messages
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class NrtMessage : pb::IMessage<NrtMessage>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<NrtMessage> _parser = new pb::MessageParser<NrtMessage>(() => new NrtMessage());
    private pb::UnknownFieldSet? _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<NrtMessage> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.NrtReflection.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 NrtMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public NrtMessage(NrtMessage other) : this() {
      _hasBits0 = other._hasBits0;
      proto3ImportMessage_ = other.proto3ImportMessage_ != null ? other.proto3ImportMessage_.Clone() : null;
      otherMessage_ = other.otherMessage_ != null ? other.otherMessage_.Clone() : null;
      text_ = other.text_;
      integer_ = other.integer_;
      blob_ = other.blob_;
      enumField_ = other.enumField_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

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

    /// <summary>Field number for the "proto3_import_message" field.</summary>
    public const int Proto3ImportMessageFieldNumber = 1;
    private global::Google.Protobuf.TestProtos.ImportMessage? proto3ImportMessage_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.TestProtos.ImportMessage? Proto3ImportMessage {
      get { return proto3ImportMessage_; }
      set {
        proto3ImportMessage_ = value;
      }
    }

    /// <summary>Field number for the "other_message" field.</summary>
    public const int OtherMessageFieldNumber = 2;
    private global::Google.Protobuf.TestProtos.OtherNrtMessage? otherMessage_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.TestProtos.OtherNrtMessage? OtherMessage {
      get { return otherMessage_; }
      set {
        otherMessage_ = value;
      }
    }

    /// <summary>Field number for the "text" field.</summary>
    public const int TextFieldNumber = 3;
    private readonly static string TextDefaultValue = "";

    private string? text_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string Text {
      get { return text_ ?? TextDefaultValue; }
      set {
        text_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "text" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasText {
      get { return text_ != null; }
    }
    /// <summary>Clears the value of the "text" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearText() {
      text_ = null;
    }

    /// <summary>Field number for the "integer" field.</summary>
    public const int IntegerFieldNumber = 4;
    private readonly static int IntegerDefaultValue = 0;

    private int integer_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int Integer {
      get { if ((_hasBits0 & 1) != 0) { return integer_; } else { return IntegerDefaultValue; } }
      set {
        _hasBits0 |= 1;
        integer_ = value;
      }
    }
    /// <summary>Gets whether the "integer" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasInteger {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "integer" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearInteger() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "blob" field.</summary>
    public const int BlobFieldNumber = 5;
    private readonly static pb::ByteString BlobDefaultValue = pb::ByteString.Empty;

    private pb::ByteString? blob_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pb::ByteString Blob {
      get { return blob_ ?? BlobDefaultValue; }
      set {
        blob_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "blob" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasBlob {
      get { return blob_ != null; }
    }
    /// <summary>Clears the value of the "blob" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearBlob() {
      blob_ = null;
    }

    /// <summary>Field number for the "enum_field" field.</summary>
    public const int EnumFieldFieldNumber = 6;
    private readonly static global::Google.Protobuf.TestProtos.NrtEnum EnumFieldDefaultValue = global::Google.Protobuf.TestProtos.NrtEnum.Unspecified;

    private global::Google.Protobuf.TestProtos.NrtEnum enumField_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.TestProtos.NrtEnum EnumField {
      get { if ((_hasBits0 & 2) != 0) { return enumField_; } else { return EnumFieldDefaultValue; } }
      set {
        _hasBits0 |= 2;
        enumField_ = value;
      }
    }
    /// <summary>Gets whether the "enum_field" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasEnumField {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "enum_field" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearEnumField() {
      _hasBits0 &= ~2;
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(NrtMessage? other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(Proto3ImportMessage, other.Proto3ImportMessage)) return false;
      if (!object.Equals(OtherMessage, other.OtherMessage)) return false;
      if (Text != other.Text) return false;
      if (Integer != other.Integer) return false;
      if (Blob != other.Blob) return false;
      if (EnumField != other.EnumField) 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 (proto3ImportMessage_ != null) hash ^= Proto3ImportMessage.GetHashCode();
      if (otherMessage_ != null) hash ^= OtherMessage.GetHashCode();
      if (HasText) hash ^= Text.GetHashCode();
      if (HasInteger) hash ^= Integer.GetHashCode();
      if (HasBlob) hash ^= Blob.GetHashCode();
      if (HasEnumField) hash ^= EnumField.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 (proto3ImportMessage_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(Proto3ImportMessage);
      }
      if (otherMessage_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(OtherMessage);
      }
      if (HasText) {
        output.WriteRawTag(26);
        output.WriteString(Text);
      }
      if (HasInteger) {
        output.WriteRawTag(32);
        output.WriteInt32(Integer);
      }
      if (HasBlob) {
        output.WriteRawTag(42);
        output.WriteBytes(Blob);
      }
      if (HasEnumField) {
        output.WriteRawTag(48);
        output.WriteEnum((int) EnumField);
      }
      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 (proto3ImportMessage_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(Proto3ImportMessage);
      }
      if (otherMessage_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(OtherMessage);
      }
      if (HasText) {
        output.WriteRawTag(26);
        output.WriteString(Text);
      }
      if (HasInteger) {
        output.WriteRawTag(32);
        output.WriteInt32(Integer);
      }
      if (HasBlob) {
        output.WriteRawTag(42);
        output.WriteBytes(Blob);
      }
      if (HasEnumField) {
        output.WriteRawTag(48);
        output.WriteEnum((int) EnumField);
      }
      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 (proto3ImportMessage_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Proto3ImportMessage);
      }
      if (otherMessage_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(OtherMessage);
      }
      if (HasText) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Text);
      }
      if (HasInteger) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Integer);
      }
      if (HasBlob) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Blob);
      }
      if (HasEnumField) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumField);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(NrtMessage other) {
      if (other == null) {
        return;
      }
      if (other.proto3ImportMessage_ != null) {
        if (proto3ImportMessage_ == null) {
          Proto3ImportMessage = new global::Google.Protobuf.TestProtos.ImportMessage();
        }
        Proto3ImportMessage.MergeFrom(other.Proto3ImportMessage);
      }
      if (other.otherMessage_ != null) {
        if (otherMessage_ == null) {
          OtherMessage = new global::Google.Protobuf.TestProtos.OtherNrtMessage();
        }
        OtherMessage.MergeFrom(other.OtherMessage);
      }
      if (other.HasText) {
        Text = other.Text;
      }
      if (other.HasInteger) {
        Integer = other.Integer;
      }
      if (other.HasBlob) {
        Blob = other.Blob;
      }
      if (other.HasEnumField) {
        EnumField = other.EnumField;
      }
      _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) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            if (proto3ImportMessage_ == null) {
              Proto3ImportMessage = new global::Google.Protobuf.TestProtos.ImportMessage();
            }
            input.ReadMessage(Proto3ImportMessage);
            break;
          }
          case 18: {
            if (otherMessage_ == null) {
              OtherMessage = new global::Google.Protobuf.TestProtos.OtherNrtMessage();
            }
            input.ReadMessage(OtherMessage);
            break;
          }
          case 26: {
            Text = input.ReadString();
            break;
          }
          case 32: {
            Integer = input.ReadInt32();
            break;
          }
          case 42: {
            Blob = input.ReadBytes();
            break;
          }
          case 48: {
            EnumField = (global::Google.Protobuf.TestProtos.NrtEnum) input.ReadEnum();
            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) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            if (proto3ImportMessage_ == null) {
              Proto3ImportMessage = new global::Google.Protobuf.TestProtos.ImportMessage();
            }
            input.ReadMessage(Proto3ImportMessage);
            break;
          }
          case 18: {
            if (otherMessage_ == null) {
              OtherMessage = new global::Google.Protobuf.TestProtos.OtherNrtMessage();
            }
            input.ReadMessage(OtherMessage);
            break;
          }
          case 26: {
            Text = input.ReadString();
            break;
          }
          case 32: {
            Integer = input.ReadInt32();
            break;
          }
          case 42: {
            Blob = input.ReadBytes();
            break;
          }
          case 48: {
            EnumField = (global::Google.Protobuf.TestProtos.NrtEnum) input.ReadEnum();
            break;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the NrtMessage message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class NestedMessage : pb::IMessage<NestedMessage>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
        private pb::UnknownFieldSet? _unknownFields;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.TestProtos.NrtMessage.Descriptor.NestedTypes[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 NestedMessage() {
          OnConstruction();
        }

        partial void OnConstruction();

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

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

        /// <summary>Field number for the "text" field.</summary>
        public const int TextFieldNumber = 1;
        private readonly static string TextDefaultValue = "";

        private string? text_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public string Text {
          get { return text_ ?? TextDefaultValue; }
          set {
            text_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "text" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasText {
          get { return text_ != null; }
        }
        /// <summary>Clears the value of the "text" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearText() {
          text_ = null;
        }

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Equals(NestedMessage? other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Text != other.Text) 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 (HasText) hash ^= Text.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 (HasText) {
            output.WriteRawTag(10);
            output.WriteString(Text);
          }
          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 (HasText) {
            output.WriteRawTag(10);
            output.WriteString(Text);
          }
          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 (HasText) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(Text);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(NestedMessage other) {
          if (other == null) {
            return;
          }
          if (other.HasText) {
            Text = other.Text;
          }
          _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) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 10: {
                Text = 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) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 10: {
                Text = input.ReadString();
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.NrtReflection.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 OtherNrtMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

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

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

    /// <summary>Field number for the "text" field.</summary>
    public const int TextFieldNumber = 1;
    private readonly static string TextDefaultValue = "";

    private string? text_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public string Text {
      get { return text_ ?? TextDefaultValue; }
      set {
        text_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "text" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasText {
      get { return text_ != null; }
    }
    /// <summary>Clears the value of the "text" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearText() {
      text_ = null;
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(OtherNrtMessage? other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Text != other.Text) 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 (HasText) hash ^= Text.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 (HasText) {
        output.WriteRawTag(10);
        output.WriteString(Text);
      }
      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 (HasText) {
        output.WriteRawTag(10);
        output.WriteString(Text);
      }
      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 (HasText) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Text);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(OtherNrtMessage other) {
      if (other == null) {
        return;
      }
      if (other.HasText) {
        Text = other.Text;
      }
      _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) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Text = 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) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Text = input.ReadString();
            break;
          }
        }
      }
    }
    #endif

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class ExtendableNrtMessage : pb::IExtendableMessage<ExtendableNrtMessage>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<ExtendableNrtMessage> _parser = new pb::MessageParser<ExtendableNrtMessage>(() => new ExtendableNrtMessage());
    private pb::UnknownFieldSet? _unknownFields;
    private pb::ExtensionSet<ExtendableNrtMessage>? _extensions;
    private pb::ExtensionSet<ExtendableNrtMessage>?  _Extensions { get { return _extensions; } }
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<ExtendableNrtMessage> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.NrtReflection.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 ExtendableNrtMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(ExtendableNrtMessage? other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!Equals(_extensions, other._extensions)) {
        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 (_extensions != null) {
        hash ^= _extensions.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 (_extensions != null) {
        _extensions.WriteTo(output);
      }
      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 (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      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 (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(ExtendableNrtMessage other) {
      if (other == null) {
        return;
      }
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            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) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
        }
      }
    }
    #endif

    public TValue GetExtension<TValue>(pb::Extension<ExtendableNrtMessage, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue>? GetExtension<TValue>(pb::RepeatedExtension<ExtendableNrtMessage, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<ExtendableNrtMessage, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<ExtendableNrtMessage, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<ExtendableNrtMessage, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<ExtendableNrtMessage, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<ExtendableNrtMessage, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

  }

  #endregion

}

#endregion Designer generated code
