// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: ThrowablePB.proto

package org.apache.dubbo.common.serialize.protobuf.support.wrapper;

public final class ThrowablePB {
  private ThrowablePB() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  public interface StackTraceElementProtoOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * The fully qualified name of the class containing the execution point
     * represented by the stack trace element.
     * </pre>
     *
     * <code>string class_name = 1;</code>
     */
    java.lang.String getClassName();
    /**
     * <pre>
     * The fully qualified name of the class containing the execution point
     * represented by the stack trace element.
     * </pre>
     *
     * <code>string class_name = 1;</code>
     */
    com.google.protobuf.ByteString
        getClassNameBytes();

    /**
     * <pre>
     * The name of the method containing the execution point represented by the
     * stack trace element
     * </pre>
     *
     * <code>string method_name = 2;</code>
     */
    java.lang.String getMethodName();
    /**
     * <pre>
     * The name of the method containing the execution point represented by the
     * stack trace element
     * </pre>
     *
     * <code>string method_name = 2;</code>
     */
    com.google.protobuf.ByteString
        getMethodNameBytes();

    /**
     * <pre>
     * The name of the file containing the execution point represented by the
     * stack trace element, or null if this information is unavailable.
     * </pre>
     *
     * <code>string file_name = 3;</code>
     */
    java.lang.String getFileName();
    /**
     * <pre>
     * The name of the file containing the execution point represented by the
     * stack trace element, or null if this information is unavailable.
     * </pre>
     *
     * <code>string file_name = 3;</code>
     */
    com.google.protobuf.ByteString
        getFileNameBytes();

    /**
     * <pre>
     * The line number of the source line containing the execution point represented
     * by this stack trace element, or a negative number if this information is
     * unavailable.
     * </pre>
     *
     * <code>int32 line_number = 4;</code>
     */
    int getLineNumber();
  }
  /**
   * <pre>
   * An element in a stack trace, based on the Java type of the same name.
   * See: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StackTraceElement.html
   * </pre>
   *
   * Protobuf type {@code org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto}
   */
  public  static final class StackTraceElementProto extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto)
      StackTraceElementProtoOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use StackTraceElementProto.newBuilder() to construct.
    private StackTraceElementProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private StackTraceElementProto() {
      className_ = "";
      methodName_ = "";
      fileName_ = "";
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private StackTraceElementProto(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              java.lang.String s = input.readStringRequireUtf8();

              className_ = s;
              break;
            }
            case 18: {
              java.lang.String s = input.readStringRequireUtf8();

              methodName_ = s;
              break;
            }
            case 26: {
              java.lang.String s = input.readStringRequireUtf8();

              fileName_ = s;
              break;
            }
            case 32: {

              lineNumber_ = input.readInt32();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.class, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder.class);
    }

    public static final int CLASS_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object className_;
    /**
     * <pre>
     * The fully qualified name of the class containing the execution point
     * represented by the stack trace element.
     * </pre>
     *
     * <code>string class_name = 1;</code>
     */
    public java.lang.String getClassName() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        className_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * The fully qualified name of the class containing the execution point
     * represented by the stack trace element.
     * </pre>
     *
     * <code>string class_name = 1;</code>
     */
    public com.google.protobuf.ByteString
        getClassNameBytes() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        className_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int METHOD_NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object methodName_;
    /**
     * <pre>
     * The name of the method containing the execution point represented by the
     * stack trace element
     * </pre>
     *
     * <code>string method_name = 2;</code>
     */
    public java.lang.String getMethodName() {
      java.lang.Object ref = methodName_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        methodName_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * The name of the method containing the execution point represented by the
     * stack trace element
     * </pre>
     *
     * <code>string method_name = 2;</code>
     */
    public com.google.protobuf.ByteString
        getMethodNameBytes() {
      java.lang.Object ref = methodName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        methodName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int FILE_NAME_FIELD_NUMBER = 3;
    private volatile java.lang.Object fileName_;
    /**
     * <pre>
     * The name of the file containing the execution point represented by the
     * stack trace element, or null if this information is unavailable.
     * </pre>
     *
     * <code>string file_name = 3;</code>
     */
    public java.lang.String getFileName() {
      java.lang.Object ref = fileName_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        fileName_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * The name of the file containing the execution point represented by the
     * stack trace element, or null if this information is unavailable.
     * </pre>
     *
     * <code>string file_name = 3;</code>
     */
    public com.google.protobuf.ByteString
        getFileNameBytes() {
      java.lang.Object ref = fileName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        fileName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int LINE_NUMBER_FIELD_NUMBER = 4;
    private int lineNumber_;
    /**
     * <pre>
     * The line number of the source line containing the execution point represented
     * by this stack trace element, or a negative number if this information is
     * unavailable.
     * </pre>
     *
     * <code>int32 line_number = 4;</code>
     */
    public int getLineNumber() {
      return lineNumber_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!getClassNameBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, className_);
      }
      if (!getMethodNameBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, methodName_);
      }
      if (!getFileNameBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, fileName_);
      }
      if (lineNumber_ != 0) {
        output.writeInt32(4, lineNumber_);
      }
      unknownFields.writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (!getClassNameBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, className_);
      }
      if (!getMethodNameBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, methodName_);
      }
      if (!getFileNameBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, fileName_);
      }
      if (lineNumber_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, lineNumber_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto)) {
        return super.equals(obj);
      }
      org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto other = (org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto) obj;

      if (!getClassName()
          .equals(other.getClassName())) return false;
      if (!getMethodName()
          .equals(other.getMethodName())) return false;
      if (!getFileName()
          .equals(other.getFileName())) return false;
      if (getLineNumber()
          != other.getLineNumber()) return false;
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + CLASS_NAME_FIELD_NUMBER;
      hash = (53 * hash) + getClassName().hashCode();
      hash = (37 * hash) + METHOD_NAME_FIELD_NUMBER;
      hash = (53 * hash) + getMethodName().hashCode();
      hash = (37 * hash) + FILE_NAME_FIELD_NUMBER;
      hash = (53 * hash) + getFileName().hashCode();
      hash = (37 * hash) + LINE_NUMBER_FIELD_NUMBER;
      hash = (53 * hash) + getLineNumber();
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * An element in a stack trace, based on the Java type of the same name.
     * See: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/StackTraceElement.html
     * </pre>
     *
     * Protobuf type {@code org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto)
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.class, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder.class);
      }

      // Construct using org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        className_ = "";

        methodName_ = "";

        fileName_ = "";

        lineNumber_ = 0;

        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_descriptor;
      }

      @java.lang.Override
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto getDefaultInstanceForType() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto build() {
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto buildPartial() {
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto result = new org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto(this);
        result.className_ = className_;
        result.methodName_ = methodName_;
        result.fileName_ = fileName_;
        result.lineNumber_ = lineNumber_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto) {
          return mergeFrom((org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto other) {
        if (other == org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.getDefaultInstance()) return this;
        if (!other.getClassName().isEmpty()) {
          className_ = other.className_;
          onChanged();
        }
        if (!other.getMethodName().isEmpty()) {
          methodName_ = other.methodName_;
          onChanged();
        }
        if (!other.getFileName().isEmpty()) {
          fileName_ = other.fileName_;
          onChanged();
        }
        if (other.getLineNumber() != 0) {
          setLineNumber(other.getLineNumber());
        }
        this.mergeUnknownFields(other.unknownFields);
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      private java.lang.Object className_ = "";
      /**
       * <pre>
       * The fully qualified name of the class containing the execution point
       * represented by the stack trace element.
       * </pre>
       *
       * <code>string class_name = 1;</code>
       */
      public java.lang.String getClassName() {
        java.lang.Object ref = className_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          className_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The fully qualified name of the class containing the execution point
       * represented by the stack trace element.
       * </pre>
       *
       * <code>string class_name = 1;</code>
       */
      public com.google.protobuf.ByteString
          getClassNameBytes() {
        java.lang.Object ref = className_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          className_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The fully qualified name of the class containing the execution point
       * represented by the stack trace element.
       * </pre>
       *
       * <code>string class_name = 1;</code>
       */
      public Builder setClassName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        className_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The fully qualified name of the class containing the execution point
       * represented by the stack trace element.
       * </pre>
       *
       * <code>string class_name = 1;</code>
       */
      public Builder clearClassName() {
        
        className_ = getDefaultInstance().getClassName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The fully qualified name of the class containing the execution point
       * represented by the stack trace element.
       * </pre>
       *
       * <code>string class_name = 1;</code>
       */
      public Builder setClassNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        className_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object methodName_ = "";
      /**
       * <pre>
       * The name of the method containing the execution point represented by the
       * stack trace element
       * </pre>
       *
       * <code>string method_name = 2;</code>
       */
      public java.lang.String getMethodName() {
        java.lang.Object ref = methodName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          methodName_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The name of the method containing the execution point represented by the
       * stack trace element
       * </pre>
       *
       * <code>string method_name = 2;</code>
       */
      public com.google.protobuf.ByteString
          getMethodNameBytes() {
        java.lang.Object ref = methodName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          methodName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The name of the method containing the execution point represented by the
       * stack trace element
       * </pre>
       *
       * <code>string method_name = 2;</code>
       */
      public Builder setMethodName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        methodName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name of the method containing the execution point represented by the
       * stack trace element
       * </pre>
       *
       * <code>string method_name = 2;</code>
       */
      public Builder clearMethodName() {
        
        methodName_ = getDefaultInstance().getMethodName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name of the method containing the execution point represented by the
       * stack trace element
       * </pre>
       *
       * <code>string method_name = 2;</code>
       */
      public Builder setMethodNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        methodName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object fileName_ = "";
      /**
       * <pre>
       * The name of the file containing the execution point represented by the
       * stack trace element, or null if this information is unavailable.
       * </pre>
       *
       * <code>string file_name = 3;</code>
       */
      public java.lang.String getFileName() {
        java.lang.Object ref = fileName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          fileName_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The name of the file containing the execution point represented by the
       * stack trace element, or null if this information is unavailable.
       * </pre>
       *
       * <code>string file_name = 3;</code>
       */
      public com.google.protobuf.ByteString
          getFileNameBytes() {
        java.lang.Object ref = fileName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          fileName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The name of the file containing the execution point represented by the
       * stack trace element, or null if this information is unavailable.
       * </pre>
       *
       * <code>string file_name = 3;</code>
       */
      public Builder setFileName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        fileName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name of the file containing the execution point represented by the
       * stack trace element, or null if this information is unavailable.
       * </pre>
       *
       * <code>string file_name = 3;</code>
       */
      public Builder clearFileName() {
        
        fileName_ = getDefaultInstance().getFileName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name of the file containing the execution point represented by the
       * stack trace element, or null if this information is unavailable.
       * </pre>
       *
       * <code>string file_name = 3;</code>
       */
      public Builder setFileNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        fileName_ = value;
        onChanged();
        return this;
      }

      private int lineNumber_ ;
      /**
       * <pre>
       * The line number of the source line containing the execution point represented
       * by this stack trace element, or a negative number if this information is
       * unavailable.
       * </pre>
       *
       * <code>int32 line_number = 4;</code>
       */
      public int getLineNumber() {
        return lineNumber_;
      }
      /**
       * <pre>
       * The line number of the source line containing the execution point represented
       * by this stack trace element, or a negative number if this information is
       * unavailable.
       * </pre>
       *
       * <code>int32 line_number = 4;</code>
       */
      public Builder setLineNumber(int value) {
        
        lineNumber_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The line number of the source line containing the execution point represented
       * by this stack trace element, or a negative number if this information is
       * unavailable.
       * </pre>
       *
       * <code>int32 line_number = 4;</code>
       */
      public Builder clearLineNumber() {
        
        lineNumber_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto)
    }

    // @@protoc_insertion_point(class_scope:org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto)
    private static final org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto();
    }

    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<StackTraceElementProto>
        PARSER = new com.google.protobuf.AbstractParser<StackTraceElementProto>() {
      @java.lang.Override
      public StackTraceElementProto parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new StackTraceElementProto(input, extensionRegistry);
      }
    };

    public static com.google.protobuf.Parser<StackTraceElementProto> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<StackTraceElementProto> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ThrowableProtoOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * The name of the class of the exception that was actually thrown. Downstream readers
     * of this message may or may not have the actual class available to initialize, so
     * this is just used to prefix the message of a generic exception type.
     * </pre>
     *
     * <code>string original_class_name = 1;</code>
     */
    java.lang.String getOriginalClassName();
    /**
     * <pre>
     * The name of the class of the exception that was actually thrown. Downstream readers
     * of this message may or may not have the actual class available to initialize, so
     * this is just used to prefix the message of a generic exception type.
     * </pre>
     *
     * <code>string original_class_name = 1;</code>
     */
    com.google.protobuf.ByteString
        getOriginalClassNameBytes();

    /**
     * <pre>
     * The message of this throwable. Not filled if there is no message.
     * </pre>
     *
     * <code>string original_message = 2;</code>
     */
    java.lang.String getOriginalMessage();
    /**
     * <pre>
     * The message of this throwable. Not filled if there is no message.
     * </pre>
     *
     * <code>string original_message = 2;</code>
     */
    com.google.protobuf.ByteString
        getOriginalMessageBytes();

    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    java.util.List<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto> 
        getStackTraceList();
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto getStackTrace(int index);
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    int getStackTraceCount();
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    java.util.List<? extends org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder> 
        getStackTraceOrBuilderList();
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder getStackTraceOrBuilder(
        int index);

    /**
     * <pre>
     * The cause of this Throwable. Not filled if there is no cause.
     * </pre>
     *
     * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
     */
    boolean hasCause();
    /**
     * <pre>
     * The cause of this Throwable. Not filled if there is no cause.
     * </pre>
     *
     * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
     */
    org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto getCause();
    /**
     * <pre>
     * The cause of this Throwable. Not filled if there is no cause.
     * </pre>
     *
     * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
     */
    org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProtoOrBuilder getCauseOrBuilder();
  }
  /**
   * <pre>
   * An exception that was thrown by some code, based on the Java type of the same name.
   * See: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Throwable.html
   * </pre>
   *
   * Protobuf type {@code org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto}
   */
  public  static final class ThrowableProto extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto)
      ThrowableProtoOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ThrowableProto.newBuilder() to construct.
    private ThrowableProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ThrowableProto() {
      originalClassName_ = "";
      originalMessage_ = "";
      stackTrace_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private ThrowableProto(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              java.lang.String s = input.readStringRequireUtf8();

              originalClassName_ = s;
              break;
            }
            case 18: {
              java.lang.String s = input.readStringRequireUtf8();

              originalMessage_ = s;
              break;
            }
            case 26: {
              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
                stackTrace_ = new java.util.ArrayList<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto>();
                mutable_bitField0_ |= 0x00000004;
              }
              stackTrace_.add(
                  input.readMessage(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.parser(), extensionRegistry));
              break;
            }
            case 34: {
              org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder subBuilder = null;
              if (cause_ != null) {
                subBuilder = cause_.toBuilder();
              }
              cause_ = input.readMessage(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(cause_);
                cause_ = subBuilder.buildPartial();
              }

              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000004) != 0)) {
          stackTrace_ = java.util.Collections.unmodifiableList(stackTrace_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.class, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder.class);
    }

    private int bitField0_;
    public static final int ORIGINAL_CLASS_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object originalClassName_;
    /**
     * <pre>
     * The name of the class of the exception that was actually thrown. Downstream readers
     * of this message may or may not have the actual class available to initialize, so
     * this is just used to prefix the message of a generic exception type.
     * </pre>
     *
     * <code>string original_class_name = 1;</code>
     */
    public java.lang.String getOriginalClassName() {
      java.lang.Object ref = originalClassName_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        originalClassName_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * The name of the class of the exception that was actually thrown. Downstream readers
     * of this message may or may not have the actual class available to initialize, so
     * this is just used to prefix the message of a generic exception type.
     * </pre>
     *
     * <code>string original_class_name = 1;</code>
     */
    public com.google.protobuf.ByteString
        getOriginalClassNameBytes() {
      java.lang.Object ref = originalClassName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        originalClassName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ORIGINAL_MESSAGE_FIELD_NUMBER = 2;
    private volatile java.lang.Object originalMessage_;
    /**
     * <pre>
     * The message of this throwable. Not filled if there is no message.
     * </pre>
     *
     * <code>string original_message = 2;</code>
     */
    public java.lang.String getOriginalMessage() {
      java.lang.Object ref = originalMessage_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        originalMessage_ = s;
        return s;
      }
    }
    /**
     * <pre>
     * The message of this throwable. Not filled if there is no message.
     * </pre>
     *
     * <code>string original_message = 2;</code>
     */
    public com.google.protobuf.ByteString
        getOriginalMessageBytes() {
      java.lang.Object ref = originalMessage_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        originalMessage_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int STACK_TRACE_FIELD_NUMBER = 3;
    private java.util.List<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto> stackTrace_;
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    public java.util.List<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto> getStackTraceList() {
      return stackTrace_;
    }
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    public java.util.List<? extends org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder> 
        getStackTraceOrBuilderList() {
      return stackTrace_;
    }
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    public int getStackTraceCount() {
      return stackTrace_.size();
    }
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto getStackTrace(int index) {
      return stackTrace_.get(index);
    }
    /**
     * <pre>
     * The stack trace of this Throwable.
     * </pre>
     *
     * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
     */
    public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder getStackTraceOrBuilder(
        int index) {
      return stackTrace_.get(index);
    }

    public static final int CAUSE_FIELD_NUMBER = 4;
    private org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto cause_;
    /**
     * <pre>
     * The cause of this Throwable. Not filled if there is no cause.
     * </pre>
     *
     * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
     */
    public boolean hasCause() {
      return cause_ != null;
    }
    /**
     * <pre>
     * The cause of this Throwable. Not filled if there is no cause.
     * </pre>
     *
     * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
     */
    public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto getCause() {
      return cause_ == null ? org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.getDefaultInstance() : cause_;
    }
    /**
     * <pre>
     * The cause of this Throwable. Not filled if there is no cause.
     * </pre>
     *
     * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
     */
    public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProtoOrBuilder getCauseOrBuilder() {
      return getCause();
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (!getOriginalClassNameBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, originalClassName_);
      }
      if (!getOriginalMessageBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, originalMessage_);
      }
      for (int i = 0; i < stackTrace_.size(); i++) {
        output.writeMessage(3, stackTrace_.get(i));
      }
      if (cause_ != null) {
        output.writeMessage(4, getCause());
      }
      unknownFields.writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (!getOriginalClassNameBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, originalClassName_);
      }
      if (!getOriginalMessageBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, originalMessage_);
      }
      for (int i = 0; i < stackTrace_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, stackTrace_.get(i));
      }
      if (cause_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getCause());
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto)) {
        return super.equals(obj);
      }
      org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto other = (org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto) obj;

      if (!getOriginalClassName()
          .equals(other.getOriginalClassName())) return false;
      if (!getOriginalMessage()
          .equals(other.getOriginalMessage())) return false;
      if (!getStackTraceList()
          .equals(other.getStackTraceList())) return false;
      if (hasCause() != other.hasCause()) return false;
      if (hasCause()) {
        if (!getCause()
            .equals(other.getCause())) return false;
      }
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (37 * hash) + ORIGINAL_CLASS_NAME_FIELD_NUMBER;
      hash = (53 * hash) + getOriginalClassName().hashCode();
      hash = (37 * hash) + ORIGINAL_MESSAGE_FIELD_NUMBER;
      hash = (53 * hash) + getOriginalMessage().hashCode();
      if (getStackTraceCount() > 0) {
        hash = (37 * hash) + STACK_TRACE_FIELD_NUMBER;
        hash = (53 * hash) + getStackTraceList().hashCode();
      }
      if (hasCause()) {
        hash = (37 * hash) + CAUSE_FIELD_NUMBER;
        hash = (53 * hash) + getCause().hashCode();
      }
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        com.google.protobuf.ByteString data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * An exception that was thrown by some code, based on the Java type of the same name.
     * See: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Throwable.html
     * </pre>
     *
     * Protobuf type {@code org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto)
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProtoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.class, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder.class);
      }

      // Construct using org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getStackTraceFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        originalClassName_ = "";

        originalMessage_ = "";

        if (stackTraceBuilder_ == null) {
          stackTrace_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000004);
        } else {
          stackTraceBuilder_.clear();
        }
        if (causeBuilder_ == null) {
          cause_ = null;
        } else {
          cause_ = null;
          causeBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_descriptor;
      }

      @java.lang.Override
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto getDefaultInstanceForType() {
        return org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto build() {
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto buildPartial() {
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto result = new org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        result.originalClassName_ = originalClassName_;
        result.originalMessage_ = originalMessage_;
        if (stackTraceBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            stackTrace_ = java.util.Collections.unmodifiableList(stackTrace_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.stackTrace_ = stackTrace_;
        } else {
          result.stackTrace_ = stackTraceBuilder_.build();
        }
        if (causeBuilder_ == null) {
          result.cause_ = cause_;
        } else {
          result.cause_ = causeBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto) {
          return mergeFrom((org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto other) {
        if (other == org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.getDefaultInstance()) return this;
        if (!other.getOriginalClassName().isEmpty()) {
          originalClassName_ = other.originalClassName_;
          onChanged();
        }
        if (!other.getOriginalMessage().isEmpty()) {
          originalMessage_ = other.originalMessage_;
          onChanged();
        }
        if (stackTraceBuilder_ == null) {
          if (!other.stackTrace_.isEmpty()) {
            if (stackTrace_.isEmpty()) {
              stackTrace_ = other.stackTrace_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureStackTraceIsMutable();
              stackTrace_.addAll(other.stackTrace_);
            }
            onChanged();
          }
        } else {
          if (!other.stackTrace_.isEmpty()) {
            if (stackTraceBuilder_.isEmpty()) {
              stackTraceBuilder_.dispose();
              stackTraceBuilder_ = null;
              stackTrace_ = other.stackTrace_;
              bitField0_ = (bitField0_ & ~0x00000004);
              stackTraceBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getStackTraceFieldBuilder() : null;
            } else {
              stackTraceBuilder_.addAllMessages(other.stackTrace_);
            }
          }
        }
        if (other.hasCause()) {
          mergeCause(other.getCause());
        }
        this.mergeUnknownFields(other.unknownFields);
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object originalClassName_ = "";
      /**
       * <pre>
       * The name of the class of the exception that was actually thrown. Downstream readers
       * of this message may or may not have the actual class available to initialize, so
       * this is just used to prefix the message of a generic exception type.
       * </pre>
       *
       * <code>string original_class_name = 1;</code>
       */
      public java.lang.String getOriginalClassName() {
        java.lang.Object ref = originalClassName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          originalClassName_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The name of the class of the exception that was actually thrown. Downstream readers
       * of this message may or may not have the actual class available to initialize, so
       * this is just used to prefix the message of a generic exception type.
       * </pre>
       *
       * <code>string original_class_name = 1;</code>
       */
      public com.google.protobuf.ByteString
          getOriginalClassNameBytes() {
        java.lang.Object ref = originalClassName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          originalClassName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The name of the class of the exception that was actually thrown. Downstream readers
       * of this message may or may not have the actual class available to initialize, so
       * this is just used to prefix the message of a generic exception type.
       * </pre>
       *
       * <code>string original_class_name = 1;</code>
       */
      public Builder setOriginalClassName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        originalClassName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name of the class of the exception that was actually thrown. Downstream readers
       * of this message may or may not have the actual class available to initialize, so
       * this is just used to prefix the message of a generic exception type.
       * </pre>
       *
       * <code>string original_class_name = 1;</code>
       */
      public Builder clearOriginalClassName() {
        
        originalClassName_ = getDefaultInstance().getOriginalClassName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The name of the class of the exception that was actually thrown. Downstream readers
       * of this message may or may not have the actual class available to initialize, so
       * this is just used to prefix the message of a generic exception type.
       * </pre>
       *
       * <code>string original_class_name = 1;</code>
       */
      public Builder setOriginalClassNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        originalClassName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object originalMessage_ = "";
      /**
       * <pre>
       * The message of this throwable. Not filled if there is no message.
       * </pre>
       *
       * <code>string original_message = 2;</code>
       */
      public java.lang.String getOriginalMessage() {
        java.lang.Object ref = originalMessage_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          originalMessage_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The message of this throwable. Not filled if there is no message.
       * </pre>
       *
       * <code>string original_message = 2;</code>
       */
      public com.google.protobuf.ByteString
          getOriginalMessageBytes() {
        java.lang.Object ref = originalMessage_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          originalMessage_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The message of this throwable. Not filled if there is no message.
       * </pre>
       *
       * <code>string original_message = 2;</code>
       */
      public Builder setOriginalMessage(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        originalMessage_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The message of this throwable. Not filled if there is no message.
       * </pre>
       *
       * <code>string original_message = 2;</code>
       */
      public Builder clearOriginalMessage() {
        
        originalMessage_ = getDefaultInstance().getOriginalMessage();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The message of this throwable. Not filled if there is no message.
       * </pre>
       *
       * <code>string original_message = 2;</code>
       */
      public Builder setOriginalMessageBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        originalMessage_ = value;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto> stackTrace_ =
        java.util.Collections.emptyList();
      private void ensureStackTraceIsMutable() {
        if (!((bitField0_ & 0x00000004) != 0)) {
          stackTrace_ = new java.util.ArrayList<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto>(stackTrace_);
          bitField0_ |= 0x00000004;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder> stackTraceBuilder_;

      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public java.util.List<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto> getStackTraceList() {
        if (stackTraceBuilder_ == null) {
          return java.util.Collections.unmodifiableList(stackTrace_);
        } else {
          return stackTraceBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public int getStackTraceCount() {
        if (stackTraceBuilder_ == null) {
          return stackTrace_.size();
        } else {
          return stackTraceBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto getStackTrace(int index) {
        if (stackTraceBuilder_ == null) {
          return stackTrace_.get(index);
        } else {
          return stackTraceBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder setStackTrace(
          int index, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto value) {
        if (stackTraceBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStackTraceIsMutable();
          stackTrace_.set(index, value);
          onChanged();
        } else {
          stackTraceBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder setStackTrace(
          int index, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder builderForValue) {
        if (stackTraceBuilder_ == null) {
          ensureStackTraceIsMutable();
          stackTrace_.set(index, builderForValue.build());
          onChanged();
        } else {
          stackTraceBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder addStackTrace(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto value) {
        if (stackTraceBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStackTraceIsMutable();
          stackTrace_.add(value);
          onChanged();
        } else {
          stackTraceBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder addStackTrace(
          int index, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto value) {
        if (stackTraceBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStackTraceIsMutable();
          stackTrace_.add(index, value);
          onChanged();
        } else {
          stackTraceBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder addStackTrace(
          org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder builderForValue) {
        if (stackTraceBuilder_ == null) {
          ensureStackTraceIsMutable();
          stackTrace_.add(builderForValue.build());
          onChanged();
        } else {
          stackTraceBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder addStackTrace(
          int index, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder builderForValue) {
        if (stackTraceBuilder_ == null) {
          ensureStackTraceIsMutable();
          stackTrace_.add(index, builderForValue.build());
          onChanged();
        } else {
          stackTraceBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder addAllStackTrace(
          java.lang.Iterable<? extends org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto> values) {
        if (stackTraceBuilder_ == null) {
          ensureStackTraceIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, stackTrace_);
          onChanged();
        } else {
          stackTraceBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder clearStackTrace() {
        if (stackTraceBuilder_ == null) {
          stackTrace_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000004);
          onChanged();
        } else {
          stackTraceBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public Builder removeStackTrace(int index) {
        if (stackTraceBuilder_ == null) {
          ensureStackTraceIsMutable();
          stackTrace_.remove(index);
          onChanged();
        } else {
          stackTraceBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder getStackTraceBuilder(
          int index) {
        return getStackTraceFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder getStackTraceOrBuilder(
          int index) {
        if (stackTraceBuilder_ == null) {
          return stackTrace_.get(index);  } else {
          return stackTraceBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public java.util.List<? extends org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder> 
           getStackTraceOrBuilderList() {
        if (stackTraceBuilder_ != null) {
          return stackTraceBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(stackTrace_);
        }
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder addStackTraceBuilder() {
        return getStackTraceFieldBuilder().addBuilder(
            org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.getDefaultInstance());
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder addStackTraceBuilder(
          int index) {
        return getStackTraceFieldBuilder().addBuilder(
            index, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.getDefaultInstance());
      }
      /**
       * <pre>
       * The stack trace of this Throwable.
       * </pre>
       *
       * <code>repeated .org.apache.dubbo.common.serialize.protobuf.support.wrapper.StackTraceElementProto stack_trace = 3;</code>
       */
      public java.util.List<org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder> 
           getStackTraceBuilderList() {
        return getStackTraceFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder> 
          getStackTraceFieldBuilder() {
        if (stackTraceBuilder_ == null) {
          stackTraceBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProto.Builder, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.StackTraceElementProtoOrBuilder>(
                  stackTrace_,
                  ((bitField0_ & 0x00000004) != 0),
                  getParentForChildren(),
                  isClean());
          stackTrace_ = null;
        }
        return stackTraceBuilder_;
      }

      private org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto cause_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProtoOrBuilder> causeBuilder_;
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public boolean hasCause() {
        return causeBuilder_ != null || cause_ != null;
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto getCause() {
        if (causeBuilder_ == null) {
          return cause_ == null ? org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.getDefaultInstance() : cause_;
        } else {
          return causeBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public Builder setCause(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto value) {
        if (causeBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          cause_ = value;
          onChanged();
        } else {
          causeBuilder_.setMessage(value);
        }

        return this;
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public Builder setCause(
          org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder builderForValue) {
        if (causeBuilder_ == null) {
          cause_ = builderForValue.build();
          onChanged();
        } else {
          causeBuilder_.setMessage(builderForValue.build());
        }

        return this;
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public Builder mergeCause(org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto value) {
        if (causeBuilder_ == null) {
          if (cause_ != null) {
            cause_ =
              org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.newBuilder(cause_).mergeFrom(value).buildPartial();
          } else {
            cause_ = value;
          }
          onChanged();
        } else {
          causeBuilder_.mergeFrom(value);
        }

        return this;
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public Builder clearCause() {
        if (causeBuilder_ == null) {
          cause_ = null;
          onChanged();
        } else {
          cause_ = null;
          causeBuilder_ = null;
        }

        return this;
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder getCauseBuilder() {
        
        onChanged();
        return getCauseFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProtoOrBuilder getCauseOrBuilder() {
        if (causeBuilder_ != null) {
          return causeBuilder_.getMessageOrBuilder();
        } else {
          return cause_ == null ?
              org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.getDefaultInstance() : cause_;
        }
      }
      /**
       * <pre>
       * The cause of this Throwable. Not filled if there is no cause.
       * </pre>
       *
       * <code>.org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto cause = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProtoOrBuilder> 
          getCauseFieldBuilder() {
        if (causeBuilder_ == null) {
          causeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto.Builder, org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProtoOrBuilder>(
                  getCause(),
                  getParentForChildren(),
                  isClean());
          cause_ = null;
        }
        return causeBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto)
    }

    // @@protoc_insertion_point(class_scope:org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowableProto)
    private static final org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto();
    }

    public static org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    private static final com.google.protobuf.Parser<ThrowableProto>
        PARSER = new com.google.protobuf.AbstractParser<ThrowableProto>() {
      @java.lang.Override
      public ThrowableProto parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new ThrowableProto(input, extensionRegistry);
      }
    };

    public static com.google.protobuf.Parser<ThrowableProto> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<ThrowableProto> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.dubbo.common.serialize.protobuf.support.wrapper.ThrowablePB.ThrowableProto getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static  com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\021ThrowablePB.proto\022:org.apache.dubbo.co" +
      "mmon.serialize.protobuf.support.wrapper\"" +
      "i\n\026StackTraceElementProto\022\022\n\nclass_name\030" +
      "\001 \001(\t\022\023\n\013method_name\030\002 \001(\t\022\021\n\tfile_name\030" +
      "\003 \001(\t\022\023\n\013line_number\030\004 \001(\005\"\213\002\n\016Throwable" +
      "Proto\022\033\n\023original_class_name\030\001 \001(\t\022\030\n\020or" +
      "iginal_message\030\002 \001(\t\022g\n\013stack_trace\030\003 \003(" +
      "\0132R.org.apache.dubbo.common.serialize.pr" +
      "otobuf.support.wrapper.StackTraceElement" +
      "Proto\022Y\n\005cause\030\004 \001(\0132J.org.apache.dubbo." +
      "common.serialize.protobuf.support.wrappe" +
      "r.ThrowableProtoB>\n:org.apache.dubbo.com" +
      "mon.serialize.protobuf.support.wrapperP\000" +
      "b\006proto3"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
          public com.google.protobuf.ExtensionRegistry assignDescriptors(
              com.google.protobuf.Descriptors.FileDescriptor root) {
            descriptor = root;
            return null;
          }
        };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
    internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_StackTraceElementProto_descriptor,
        new java.lang.String[] { "ClassName", "MethodName", "FileName", "LineNumber", });
    internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_common_serialize_protobuf_support_wrapper_ThrowableProto_descriptor,
        new java.lang.String[] { "OriginalClassName", "OriginalMessage", "StackTrace", "Cause", });
  }

  // @@protoc_insertion_point(outer_class_scope)
}
