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

package org.apache.dubbo.benchmark.bean;

public final class PagePB {
  private PagePB() {}
  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 PageOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.apache.dubbo.benchmark.bean.Page)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    java.util.List<org.apache.dubbo.benchmark.bean.PagePB.User> 
        getUsersList();
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.User getUsers(int index);
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    int getUsersCount();
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    java.util.List<? extends org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> 
        getUsersOrBuilderList();
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUsersOrBuilder(
        int index);

    /**
     * <code>int32 pageNo = 2;</code>
     */
    int getPageNo();

    /**
     * <code>int32 total = 3;</code>
     */
    int getTotal();
  }
  /**
   * <pre>
   *### 编译只会生成message，service生成需要借助grpc这样的插件
   * </pre>
   *
   * Protobuf type {@code org.apache.dubbo.benchmark.bean.Page}
   */
  public  static final class Page extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:org.apache.dubbo.benchmark.bean.Page)
      PageOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Page.newBuilder() to construct.
    private Page(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Page() {
      users_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private Page(
        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: {
              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
                users_ = new java.util.ArrayList<org.apache.dubbo.benchmark.bean.PagePB.User>();
                mutable_bitField0_ |= 0x00000001;
              }
              users_.add(
                  input.readMessage(org.apache.dubbo.benchmark.bean.PagePB.User.parser(), extensionRegistry));
              break;
            }
            case 16: {

              pageNo_ = input.readInt32();
              break;
            }
            case 24: {

              total_ = 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 {
        if (((mutable_bitField0_ & 0x00000001) != 0)) {
          users_ = java.util.Collections.unmodifiableList(users_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Page_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Page_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.dubbo.benchmark.bean.PagePB.Page.class, org.apache.dubbo.benchmark.bean.PagePB.Page.Builder.class);
    }

    private int bitField0_;
    public static final int USERS_FIELD_NUMBER = 1;
    private java.util.List<org.apache.dubbo.benchmark.bean.PagePB.User> users_;
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    public java.util.List<org.apache.dubbo.benchmark.bean.PagePB.User> getUsersList() {
      return users_;
    }
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    public java.util.List<? extends org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> 
        getUsersOrBuilderList() {
      return users_;
    }
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    public int getUsersCount() {
      return users_.size();
    }
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.User getUsers(int index) {
      return users_.get(index);
    }
    /**
     * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUsersOrBuilder(
        int index) {
      return users_.get(index);
    }

    public static final int PAGENO_FIELD_NUMBER = 2;
    private int pageNo_;
    /**
     * <code>int32 pageNo = 2;</code>
     */
    public int getPageNo() {
      return pageNo_;
    }

    public static final int TOTAL_FIELD_NUMBER = 3;
    private int total_;
    /**
     * <code>int32 total = 3;</code>
     */
    public int getTotal() {
      return total_;
    }

    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 {
      for (int i = 0; i < users_.size(); i++) {
        output.writeMessage(1, users_.get(i));
      }
      if (pageNo_ != 0) {
        output.writeInt32(2, pageNo_);
      }
      if (total_ != 0) {
        output.writeInt32(3, total_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      for (int i = 0; i < users_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, users_.get(i));
      }
      if (pageNo_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, pageNo_);
      }
      if (total_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, total_);
      }
      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.benchmark.bean.PagePB.Page)) {
        return super.equals(obj);
      }
      org.apache.dubbo.benchmark.bean.PagePB.Page other = (org.apache.dubbo.benchmark.bean.PagePB.Page) obj;

      if (!getUsersList()
          .equals(other.getUsersList())) return false;
      if (getPageNo()
          != other.getPageNo()) return false;
      if (getTotal()
          != other.getTotal()) 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();
      if (getUsersCount() > 0) {
        hash = (37 * hash) + USERS_FIELD_NUMBER;
        hash = (53 * hash) + getUsersList().hashCode();
      }
      hash = (37 * hash) + PAGENO_FIELD_NUMBER;
      hash = (53 * hash) + getPageNo();
      hash = (37 * hash) + TOTAL_FIELD_NUMBER;
      hash = (53 * hash) + getTotal();
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.Page parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Page 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.benchmark.bean.PagePB.Page parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Page 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.benchmark.bean.PagePB.Page parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Page parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Page parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Page 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.benchmark.bean.PagePB.Page parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Page 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.benchmark.bean.PagePB.Page parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Page 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.benchmark.bean.PagePB.Page 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>
     *### 编译只会生成message，service生成需要借助grpc这样的插件
     * </pre>
     *
     * Protobuf type {@code org.apache.dubbo.benchmark.bean.Page}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.apache.dubbo.benchmark.bean.Page)
        org.apache.dubbo.benchmark.bean.PagePB.PageOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Page_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Page_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.dubbo.benchmark.bean.PagePB.Page.class, org.apache.dubbo.benchmark.bean.PagePB.Page.Builder.class);
      }

      // Construct using org.apache.dubbo.benchmark.bean.PagePB.Page.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getUsersFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (usersBuilder_ == null) {
          users_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          usersBuilder_.clear();
        }
        pageNo_ = 0;

        total_ = 0;

        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Page_descriptor;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Page getDefaultInstanceForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.Page.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Page build() {
        org.apache.dubbo.benchmark.bean.PagePB.Page result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Page buildPartial() {
        org.apache.dubbo.benchmark.bean.PagePB.Page result = new org.apache.dubbo.benchmark.bean.PagePB.Page(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (usersBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            users_ = java.util.Collections.unmodifiableList(users_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.users_ = users_;
        } else {
          result.users_ = usersBuilder_.build();
        }
        result.pageNo_ = pageNo_;
        result.total_ = total_;
        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.benchmark.bean.PagePB.Page) {
          return mergeFrom((org.apache.dubbo.benchmark.bean.PagePB.Page)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.dubbo.benchmark.bean.PagePB.Page other) {
        if (other == org.apache.dubbo.benchmark.bean.PagePB.Page.getDefaultInstance()) return this;
        if (usersBuilder_ == null) {
          if (!other.users_.isEmpty()) {
            if (users_.isEmpty()) {
              users_ = other.users_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureUsersIsMutable();
              users_.addAll(other.users_);
            }
            onChanged();
          }
        } else {
          if (!other.users_.isEmpty()) {
            if (usersBuilder_.isEmpty()) {
              usersBuilder_.dispose();
              usersBuilder_ = null;
              users_ = other.users_;
              bitField0_ = (bitField0_ & ~0x00000001);
              usersBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getUsersFieldBuilder() : null;
            } else {
              usersBuilder_.addAllMessages(other.users_);
            }
          }
        }
        if (other.getPageNo() != 0) {
          setPageNo(other.getPageNo());
        }
        if (other.getTotal() != 0) {
          setTotal(other.getTotal());
        }
        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.benchmark.bean.PagePB.Page parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.dubbo.benchmark.bean.PagePB.Page) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.apache.dubbo.benchmark.bean.PagePB.User> users_ =
        java.util.Collections.emptyList();
      private void ensureUsersIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          users_ = new java.util.ArrayList<org.apache.dubbo.benchmark.bean.PagePB.User>(users_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> usersBuilder_;

      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public java.util.List<org.apache.dubbo.benchmark.bean.PagePB.User> getUsersList() {
        if (usersBuilder_ == null) {
          return java.util.Collections.unmodifiableList(users_);
        } else {
          return usersBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public int getUsersCount() {
        if (usersBuilder_ == null) {
          return users_.size();
        } else {
          return usersBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User getUsers(int index) {
        if (usersBuilder_ == null) {
          return users_.get(index);
        } else {
          return usersBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder setUsers(
          int index, org.apache.dubbo.benchmark.bean.PagePB.User value) {
        if (usersBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureUsersIsMutable();
          users_.set(index, value);
          onChanged();
        } else {
          usersBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder setUsers(
          int index, org.apache.dubbo.benchmark.bean.PagePB.User.Builder builderForValue) {
        if (usersBuilder_ == null) {
          ensureUsersIsMutable();
          users_.set(index, builderForValue.build());
          onChanged();
        } else {
          usersBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder addUsers(org.apache.dubbo.benchmark.bean.PagePB.User value) {
        if (usersBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureUsersIsMutable();
          users_.add(value);
          onChanged();
        } else {
          usersBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder addUsers(
          int index, org.apache.dubbo.benchmark.bean.PagePB.User value) {
        if (usersBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureUsersIsMutable();
          users_.add(index, value);
          onChanged();
        } else {
          usersBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder addUsers(
          org.apache.dubbo.benchmark.bean.PagePB.User.Builder builderForValue) {
        if (usersBuilder_ == null) {
          ensureUsersIsMutable();
          users_.add(builderForValue.build());
          onChanged();
        } else {
          usersBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder addUsers(
          int index, org.apache.dubbo.benchmark.bean.PagePB.User.Builder builderForValue) {
        if (usersBuilder_ == null) {
          ensureUsersIsMutable();
          users_.add(index, builderForValue.build());
          onChanged();
        } else {
          usersBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder addAllUsers(
          java.lang.Iterable<? extends org.apache.dubbo.benchmark.bean.PagePB.User> values) {
        if (usersBuilder_ == null) {
          ensureUsersIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, users_);
          onChanged();
        } else {
          usersBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder clearUsers() {
        if (usersBuilder_ == null) {
          users_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          usersBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public Builder removeUsers(int index) {
        if (usersBuilder_ == null) {
          ensureUsersIsMutable();
          users_.remove(index);
          onChanged();
        } else {
          usersBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User.Builder getUsersBuilder(
          int index) {
        return getUsersFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUsersOrBuilder(
          int index) {
        if (usersBuilder_ == null) {
          return users_.get(index);  } else {
          return usersBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public java.util.List<? extends org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> 
           getUsersOrBuilderList() {
        if (usersBuilder_ != null) {
          return usersBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(users_);
        }
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User.Builder addUsersBuilder() {
        return getUsersFieldBuilder().addBuilder(
            org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance());
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User.Builder addUsersBuilder(
          int index) {
        return getUsersFieldBuilder().addBuilder(
            index, org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance());
      }
      /**
       * <code>repeated .org.apache.dubbo.benchmark.bean.User users = 1;</code>
       */
      public java.util.List<org.apache.dubbo.benchmark.bean.PagePB.User.Builder> 
           getUsersBuilderList() {
        return getUsersFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> 
          getUsersFieldBuilder() {
        if (usersBuilder_ == null) {
          usersBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder>(
                  users_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          users_ = null;
        }
        return usersBuilder_;
      }

      private int pageNo_ ;
      /**
       * <code>int32 pageNo = 2;</code>
       */
      public int getPageNo() {
        return pageNo_;
      }
      /**
       * <code>int32 pageNo = 2;</code>
       */
      public Builder setPageNo(int value) {
        
        pageNo_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>int32 pageNo = 2;</code>
       */
      public Builder clearPageNo() {
        
        pageNo_ = 0;
        onChanged();
        return this;
      }

      private int total_ ;
      /**
       * <code>int32 total = 3;</code>
       */
      public int getTotal() {
        return total_;
      }
      /**
       * <code>int32 total = 3;</code>
       */
      public Builder setTotal(int value) {
        
        total_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>int32 total = 3;</code>
       */
      public Builder clearTotal() {
        
        total_ = 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.benchmark.bean.Page)
    }

    // @@protoc_insertion_point(class_scope:org.apache.dubbo.benchmark.bean.Page)
    private static final org.apache.dubbo.benchmark.bean.PagePB.Page DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.dubbo.benchmark.bean.PagePB.Page();
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.Page getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

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

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

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

    @java.lang.Override
    public org.apache.dubbo.benchmark.bean.PagePB.Page getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface UserOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.apache.dubbo.benchmark.bean.User)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>int64 id = 1;</code>
     */
    long getId();

    /**
     * <code>string name = 2;</code>
     */
    java.lang.String getName();
    /**
     * <code>string name = 2;</code>
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>int32 sex = 3;</code>
     */
    int getSex();

    /**
     * <code>.google.protobuf.Timestamp birthday = 4;</code>
     */
    boolean hasBirthday();
    /**
     * <code>.google.protobuf.Timestamp birthday = 4;</code>
     */
    com.google.protobuf.Timestamp getBirthday();
    /**
     * <code>.google.protobuf.Timestamp birthday = 4;</code>
     */
    com.google.protobuf.TimestampOrBuilder getBirthdayOrBuilder();

    /**
     * <code>string email = 5;</code>
     */
    java.lang.String getEmail();
    /**
     * <code>string email = 5;</code>
     */
    com.google.protobuf.ByteString
        getEmailBytes();

    /**
     * <code>string mobile = 6;</code>
     */
    java.lang.String getMobile();
    /**
     * <code>string mobile = 6;</code>
     */
    com.google.protobuf.ByteString
        getMobileBytes();

    /**
     * <code>string address = 7;</code>
     */
    java.lang.String getAddress();
    /**
     * <code>string address = 7;</code>
     */
    com.google.protobuf.ByteString
        getAddressBytes();

    /**
     * <code>string icon = 8;</code>
     */
    java.lang.String getIcon();
    /**
     * <code>string icon = 8;</code>
     */
    com.google.protobuf.ByteString
        getIconBytes();

    /**
     * <code>repeated int32 permissions = 9;</code>
     */
    java.util.List<java.lang.Integer> getPermissionsList();
    /**
     * <code>repeated int32 permissions = 9;</code>
     */
    int getPermissionsCount();
    /**
     * <code>repeated int32 permissions = 9;</code>
     */
    int getPermissions(int index);

    /**
     * <code>int32 status = 10;</code>
     */
    int getStatus();

    /**
     * <code>.google.protobuf.Timestamp createTime = 11;</code>
     */
    boolean hasCreateTime();
    /**
     * <code>.google.protobuf.Timestamp createTime = 11;</code>
     */
    com.google.protobuf.Timestamp getCreateTime();
    /**
     * <code>.google.protobuf.Timestamp createTime = 11;</code>
     */
    com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder();

    /**
     * <code>.google.protobuf.Timestamp updateTime = 12;</code>
     */
    boolean hasUpdateTime();
    /**
     * <code>.google.protobuf.Timestamp updateTime = 12;</code>
     */
    com.google.protobuf.Timestamp getUpdateTime();
    /**
     * <code>.google.protobuf.Timestamp updateTime = 12;</code>
     */
    com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder();
  }
  /**
   * Protobuf type {@code org.apache.dubbo.benchmark.bean.User}
   */
  public  static final class User extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:org.apache.dubbo.benchmark.bean.User)
      UserOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use User.newBuilder() to construct.
    private User(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private User() {
      name_ = "";
      email_ = "";
      mobile_ = "";
      address_ = "";
      icon_ = "";
      permissions_ = emptyIntList();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private User(
        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 8: {

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

              name_ = s;
              break;
            }
            case 24: {

              sex_ = input.readInt32();
              break;
            }
            case 34: {
              com.google.protobuf.Timestamp.Builder subBuilder = null;
              if (birthday_ != null) {
                subBuilder = birthday_.toBuilder();
              }
              birthday_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(birthday_);
                birthday_ = subBuilder.buildPartial();
              }

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

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

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

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

              icon_ = s;
              break;
            }
            case 72: {
              if (!((mutable_bitField0_ & 0x00000100) != 0)) {
                permissions_ = newIntList();
                mutable_bitField0_ |= 0x00000100;
              }
              permissions_.addInt(input.readInt32());
              break;
            }
            case 74: {
              int length = input.readRawVarint32();
              int limit = input.pushLimit(length);
              if (!((mutable_bitField0_ & 0x00000100) != 0) && input.getBytesUntilLimit() > 0) {
                permissions_ = newIntList();
                mutable_bitField0_ |= 0x00000100;
              }
              while (input.getBytesUntilLimit() > 0) {
                permissions_.addInt(input.readInt32());
              }
              input.popLimit(limit);
              break;
            }
            case 80: {

              status_ = input.readInt32();
              break;
            }
            case 90: {
              com.google.protobuf.Timestamp.Builder subBuilder = null;
              if (createTime_ != null) {
                subBuilder = createTime_.toBuilder();
              }
              createTime_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(createTime_);
                createTime_ = subBuilder.buildPartial();
              }

              break;
            }
            case 98: {
              com.google.protobuf.Timestamp.Builder subBuilder = null;
              if (updateTime_ != null) {
                subBuilder = updateTime_.toBuilder();
              }
              updateTime_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(updateTime_);
                updateTime_ = 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_ & 0x00000100) != 0)) {
          permissions_.makeImmutable(); // C
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_User_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_User_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.dubbo.benchmark.bean.PagePB.User.class, org.apache.dubbo.benchmark.bean.PagePB.User.Builder.class);
    }

    private int bitField0_;
    public static final int ID_FIELD_NUMBER = 1;
    private long id_;
    /**
     * <code>int64 id = 1;</code>
     */
    public long getId() {
      return id_;
    }

    public static final int NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object name_;
    /**
     * <code>string name = 2;</code>
     */
    public java.lang.String getName() {
      java.lang.Object ref = name_;
      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();
        name_ = s;
        return s;
      }
    }
    /**
     * <code>string name = 2;</code>
     */
    public com.google.protobuf.ByteString
        getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SEX_FIELD_NUMBER = 3;
    private int sex_;
    /**
     * <code>int32 sex = 3;</code>
     */
    public int getSex() {
      return sex_;
    }

    public static final int BIRTHDAY_FIELD_NUMBER = 4;
    private com.google.protobuf.Timestamp birthday_;
    /**
     * <code>.google.protobuf.Timestamp birthday = 4;</code>
     */
    public boolean hasBirthday() {
      return birthday_ != null;
    }
    /**
     * <code>.google.protobuf.Timestamp birthday = 4;</code>
     */
    public com.google.protobuf.Timestamp getBirthday() {
      return birthday_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : birthday_;
    }
    /**
     * <code>.google.protobuf.Timestamp birthday = 4;</code>
     */
    public com.google.protobuf.TimestampOrBuilder getBirthdayOrBuilder() {
      return getBirthday();
    }

    public static final int EMAIL_FIELD_NUMBER = 5;
    private volatile java.lang.Object email_;
    /**
     * <code>string email = 5;</code>
     */
    public java.lang.String getEmail() {
      java.lang.Object ref = email_;
      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();
        email_ = s;
        return s;
      }
    }
    /**
     * <code>string email = 5;</code>
     */
    public com.google.protobuf.ByteString
        getEmailBytes() {
      java.lang.Object ref = email_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        email_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int MOBILE_FIELD_NUMBER = 6;
    private volatile java.lang.Object mobile_;
    /**
     * <code>string mobile = 6;</code>
     */
    public java.lang.String getMobile() {
      java.lang.Object ref = mobile_;
      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();
        mobile_ = s;
        return s;
      }
    }
    /**
     * <code>string mobile = 6;</code>
     */
    public com.google.protobuf.ByteString
        getMobileBytes() {
      java.lang.Object ref = mobile_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        mobile_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ADDRESS_FIELD_NUMBER = 7;
    private volatile java.lang.Object address_;
    /**
     * <code>string address = 7;</code>
     */
    public java.lang.String getAddress() {
      java.lang.Object ref = address_;
      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();
        address_ = s;
        return s;
      }
    }
    /**
     * <code>string address = 7;</code>
     */
    public com.google.protobuf.ByteString
        getAddressBytes() {
      java.lang.Object ref = address_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        address_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ICON_FIELD_NUMBER = 8;
    private volatile java.lang.Object icon_;
    /**
     * <code>string icon = 8;</code>
     */
    public java.lang.String getIcon() {
      java.lang.Object ref = icon_;
      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();
        icon_ = s;
        return s;
      }
    }
    /**
     * <code>string icon = 8;</code>
     */
    public com.google.protobuf.ByteString
        getIconBytes() {
      java.lang.Object ref = icon_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        icon_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int PERMISSIONS_FIELD_NUMBER = 9;
    private com.google.protobuf.Internal.IntList permissions_;
    /**
     * <code>repeated int32 permissions = 9;</code>
     */
    public java.util.List<java.lang.Integer>
        getPermissionsList() {
      return permissions_;
    }
    /**
     * <code>repeated int32 permissions = 9;</code>
     */
    public int getPermissionsCount() {
      return permissions_.size();
    }
    /**
     * <code>repeated int32 permissions = 9;</code>
     */
    public int getPermissions(int index) {
      return permissions_.getInt(index);
    }
    private int permissionsMemoizedSerializedSize = -1;

    public static final int STATUS_FIELD_NUMBER = 10;
    private int status_;
    /**
     * <code>int32 status = 10;</code>
     */
    public int getStatus() {
      return status_;
    }

    public static final int CREATETIME_FIELD_NUMBER = 11;
    private com.google.protobuf.Timestamp createTime_;
    /**
     * <code>.google.protobuf.Timestamp createTime = 11;</code>
     */
    public boolean hasCreateTime() {
      return createTime_ != null;
    }
    /**
     * <code>.google.protobuf.Timestamp createTime = 11;</code>
     */
    public com.google.protobuf.Timestamp getCreateTime() {
      return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_;
    }
    /**
     * <code>.google.protobuf.Timestamp createTime = 11;</code>
     */
    public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() {
      return getCreateTime();
    }

    public static final int UPDATETIME_FIELD_NUMBER = 12;
    private com.google.protobuf.Timestamp updateTime_;
    /**
     * <code>.google.protobuf.Timestamp updateTime = 12;</code>
     */
    public boolean hasUpdateTime() {
      return updateTime_ != null;
    }
    /**
     * <code>.google.protobuf.Timestamp updateTime = 12;</code>
     */
    public com.google.protobuf.Timestamp getUpdateTime() {
      return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_;
    }
    /**
     * <code>.google.protobuf.Timestamp updateTime = 12;</code>
     */
    public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() {
      return getUpdateTime();
    }

    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 {
      getSerializedSize();
      if (id_ != 0L) {
        output.writeInt64(1, id_);
      }
      if (!getNameBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, name_);
      }
      if (sex_ != 0) {
        output.writeInt32(3, sex_);
      }
      if (birthday_ != null) {
        output.writeMessage(4, getBirthday());
      }
      if (!getEmailBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, email_);
      }
      if (!getMobileBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, mobile_);
      }
      if (!getAddressBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 7, address_);
      }
      if (!getIconBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 8, icon_);
      }
      if (getPermissionsList().size() > 0) {
        output.writeUInt32NoTag(74);
        output.writeUInt32NoTag(permissionsMemoizedSerializedSize);
      }
      for (int i = 0; i < permissions_.size(); i++) {
        output.writeInt32NoTag(permissions_.getInt(i));
      }
      if (status_ != 0) {
        output.writeInt32(10, status_);
      }
      if (createTime_ != null) {
        output.writeMessage(11, getCreateTime());
      }
      if (updateTime_ != null) {
        output.writeMessage(12, getUpdateTime());
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (id_ != 0L) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, id_);
      }
      if (!getNameBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_);
      }
      if (sex_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, sex_);
      }
      if (birthday_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getBirthday());
      }
      if (!getEmailBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, email_);
      }
      if (!getMobileBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, mobile_);
      }
      if (!getAddressBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, address_);
      }
      if (!getIconBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, icon_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < permissions_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeInt32SizeNoTag(permissions_.getInt(i));
        }
        size += dataSize;
        if (!getPermissionsList().isEmpty()) {
          size += 1;
          size += com.google.protobuf.CodedOutputStream
              .computeInt32SizeNoTag(dataSize);
        }
        permissionsMemoizedSerializedSize = dataSize;
      }
      if (status_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(10, status_);
      }
      if (createTime_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(11, getCreateTime());
      }
      if (updateTime_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(12, getUpdateTime());
      }
      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.benchmark.bean.PagePB.User)) {
        return super.equals(obj);
      }
      org.apache.dubbo.benchmark.bean.PagePB.User other = (org.apache.dubbo.benchmark.bean.PagePB.User) obj;

      if (getId()
          != other.getId()) return false;
      if (!getName()
          .equals(other.getName())) return false;
      if (getSex()
          != other.getSex()) return false;
      if (hasBirthday() != other.hasBirthday()) return false;
      if (hasBirthday()) {
        if (!getBirthday()
            .equals(other.getBirthday())) return false;
      }
      if (!getEmail()
          .equals(other.getEmail())) return false;
      if (!getMobile()
          .equals(other.getMobile())) return false;
      if (!getAddress()
          .equals(other.getAddress())) return false;
      if (!getIcon()
          .equals(other.getIcon())) return false;
      if (!getPermissionsList()
          .equals(other.getPermissionsList())) return false;
      if (getStatus()
          != other.getStatus()) return false;
      if (hasCreateTime() != other.hasCreateTime()) return false;
      if (hasCreateTime()) {
        if (!getCreateTime()
            .equals(other.getCreateTime())) return false;
      }
      if (hasUpdateTime() != other.hasUpdateTime()) return false;
      if (hasUpdateTime()) {
        if (!getUpdateTime()
            .equals(other.getUpdateTime())) 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) + ID_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
          getId());
      hash = (37 * hash) + NAME_FIELD_NUMBER;
      hash = (53 * hash) + getName().hashCode();
      hash = (37 * hash) + SEX_FIELD_NUMBER;
      hash = (53 * hash) + getSex();
      if (hasBirthday()) {
        hash = (37 * hash) + BIRTHDAY_FIELD_NUMBER;
        hash = (53 * hash) + getBirthday().hashCode();
      }
      hash = (37 * hash) + EMAIL_FIELD_NUMBER;
      hash = (53 * hash) + getEmail().hashCode();
      hash = (37 * hash) + MOBILE_FIELD_NUMBER;
      hash = (53 * hash) + getMobile().hashCode();
      hash = (37 * hash) + ADDRESS_FIELD_NUMBER;
      hash = (53 * hash) + getAddress().hashCode();
      hash = (37 * hash) + ICON_FIELD_NUMBER;
      hash = (53 * hash) + getIcon().hashCode();
      if (getPermissionsCount() > 0) {
        hash = (37 * hash) + PERMISSIONS_FIELD_NUMBER;
        hash = (53 * hash) + getPermissionsList().hashCode();
      }
      hash = (37 * hash) + STATUS_FIELD_NUMBER;
      hash = (53 * hash) + getStatus();
      if (hasCreateTime()) {
        hash = (37 * hash) + CREATETIME_FIELD_NUMBER;
        hash = (53 * hash) + getCreateTime().hashCode();
      }
      if (hasUpdateTime()) {
        hash = (37 * hash) + UPDATETIME_FIELD_NUMBER;
        hash = (53 * hash) + getUpdateTime().hashCode();
      }
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.User parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.User 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.benchmark.bean.PagePB.User parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.User 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.benchmark.bean.PagePB.User parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.User parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.User parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.User 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.benchmark.bean.PagePB.User parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.User 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.benchmark.bean.PagePB.User parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.User 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.benchmark.bean.PagePB.User 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;
    }
    /**
     * Protobuf type {@code org.apache.dubbo.benchmark.bean.User}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.apache.dubbo.benchmark.bean.User)
        org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_User_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_User_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.dubbo.benchmark.bean.PagePB.User.class, org.apache.dubbo.benchmark.bean.PagePB.User.Builder.class);
      }

      // Construct using org.apache.dubbo.benchmark.bean.PagePB.User.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();
        id_ = 0L;

        name_ = "";

        sex_ = 0;

        if (birthdayBuilder_ == null) {
          birthday_ = null;
        } else {
          birthday_ = null;
          birthdayBuilder_ = null;
        }
        email_ = "";

        mobile_ = "";

        address_ = "";

        icon_ = "";

        permissions_ = emptyIntList();
        bitField0_ = (bitField0_ & ~0x00000100);
        status_ = 0;

        if (createTimeBuilder_ == null) {
          createTime_ = null;
        } else {
          createTime_ = null;
          createTimeBuilder_ = null;
        }
        if (updateTimeBuilder_ == null) {
          updateTime_ = null;
        } else {
          updateTime_ = null;
          updateTimeBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_User_descriptor;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.User getDefaultInstanceForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.User build() {
        org.apache.dubbo.benchmark.bean.PagePB.User result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.User buildPartial() {
        org.apache.dubbo.benchmark.bean.PagePB.User result = new org.apache.dubbo.benchmark.bean.PagePB.User(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        result.id_ = id_;
        result.name_ = name_;
        result.sex_ = sex_;
        if (birthdayBuilder_ == null) {
          result.birthday_ = birthday_;
        } else {
          result.birthday_ = birthdayBuilder_.build();
        }
        result.email_ = email_;
        result.mobile_ = mobile_;
        result.address_ = address_;
        result.icon_ = icon_;
        if (((bitField0_ & 0x00000100) != 0)) {
          permissions_.makeImmutable();
          bitField0_ = (bitField0_ & ~0x00000100);
        }
        result.permissions_ = permissions_;
        result.status_ = status_;
        if (createTimeBuilder_ == null) {
          result.createTime_ = createTime_;
        } else {
          result.createTime_ = createTimeBuilder_.build();
        }
        if (updateTimeBuilder_ == null) {
          result.updateTime_ = updateTime_;
        } else {
          result.updateTime_ = updateTimeBuilder_.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.benchmark.bean.PagePB.User) {
          return mergeFrom((org.apache.dubbo.benchmark.bean.PagePB.User)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.dubbo.benchmark.bean.PagePB.User other) {
        if (other == org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance()) return this;
        if (other.getId() != 0L) {
          setId(other.getId());
        }
        if (!other.getName().isEmpty()) {
          name_ = other.name_;
          onChanged();
        }
        if (other.getSex() != 0) {
          setSex(other.getSex());
        }
        if (other.hasBirthday()) {
          mergeBirthday(other.getBirthday());
        }
        if (!other.getEmail().isEmpty()) {
          email_ = other.email_;
          onChanged();
        }
        if (!other.getMobile().isEmpty()) {
          mobile_ = other.mobile_;
          onChanged();
        }
        if (!other.getAddress().isEmpty()) {
          address_ = other.address_;
          onChanged();
        }
        if (!other.getIcon().isEmpty()) {
          icon_ = other.icon_;
          onChanged();
        }
        if (!other.permissions_.isEmpty()) {
          if (permissions_.isEmpty()) {
            permissions_ = other.permissions_;
            bitField0_ = (bitField0_ & ~0x00000100);
          } else {
            ensurePermissionsIsMutable();
            permissions_.addAll(other.permissions_);
          }
          onChanged();
        }
        if (other.getStatus() != 0) {
          setStatus(other.getStatus());
        }
        if (other.hasCreateTime()) {
          mergeCreateTime(other.getCreateTime());
        }
        if (other.hasUpdateTime()) {
          mergeUpdateTime(other.getUpdateTime());
        }
        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.benchmark.bean.PagePB.User parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.dubbo.benchmark.bean.PagePB.User) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private long id_ ;
      /**
       * <code>int64 id = 1;</code>
       */
      public long getId() {
        return id_;
      }
      /**
       * <code>int64 id = 1;</code>
       */
      public Builder setId(long value) {
        
        id_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>int64 id = 1;</code>
       */
      public Builder clearId() {
        
        id_ = 0L;
        onChanged();
        return this;
      }

      private java.lang.Object name_ = "";
      /**
       * <code>string name = 2;</code>
       */
      public java.lang.String getName() {
        java.lang.Object ref = name_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          name_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>string name = 2;</code>
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        java.lang.Object ref = name_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          name_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string name = 2;</code>
       */
      public Builder setName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        name_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>string name = 2;</code>
       */
      public Builder clearName() {
        
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      /**
       * <code>string name = 2;</code>
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        name_ = value;
        onChanged();
        return this;
      }

      private int sex_ ;
      /**
       * <code>int32 sex = 3;</code>
       */
      public int getSex() {
        return sex_;
      }
      /**
       * <code>int32 sex = 3;</code>
       */
      public Builder setSex(int value) {
        
        sex_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>int32 sex = 3;</code>
       */
      public Builder clearSex() {
        
        sex_ = 0;
        onChanged();
        return this;
      }

      private com.google.protobuf.Timestamp birthday_;
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> birthdayBuilder_;
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public boolean hasBirthday() {
        return birthdayBuilder_ != null || birthday_ != null;
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public com.google.protobuf.Timestamp getBirthday() {
        if (birthdayBuilder_ == null) {
          return birthday_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : birthday_;
        } else {
          return birthdayBuilder_.getMessage();
        }
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public Builder setBirthday(com.google.protobuf.Timestamp value) {
        if (birthdayBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          birthday_ = value;
          onChanged();
        } else {
          birthdayBuilder_.setMessage(value);
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public Builder setBirthday(
          com.google.protobuf.Timestamp.Builder builderForValue) {
        if (birthdayBuilder_ == null) {
          birthday_ = builderForValue.build();
          onChanged();
        } else {
          birthdayBuilder_.setMessage(builderForValue.build());
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public Builder mergeBirthday(com.google.protobuf.Timestamp value) {
        if (birthdayBuilder_ == null) {
          if (birthday_ != null) {
            birthday_ =
              com.google.protobuf.Timestamp.newBuilder(birthday_).mergeFrom(value).buildPartial();
          } else {
            birthday_ = value;
          }
          onChanged();
        } else {
          birthdayBuilder_.mergeFrom(value);
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public Builder clearBirthday() {
        if (birthdayBuilder_ == null) {
          birthday_ = null;
          onChanged();
        } else {
          birthday_ = null;
          birthdayBuilder_ = null;
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public com.google.protobuf.Timestamp.Builder getBirthdayBuilder() {
        
        onChanged();
        return getBirthdayFieldBuilder().getBuilder();
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      public com.google.protobuf.TimestampOrBuilder getBirthdayOrBuilder() {
        if (birthdayBuilder_ != null) {
          return birthdayBuilder_.getMessageOrBuilder();
        } else {
          return birthday_ == null ?
              com.google.protobuf.Timestamp.getDefaultInstance() : birthday_;
        }
      }
      /**
       * <code>.google.protobuf.Timestamp birthday = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
          getBirthdayFieldBuilder() {
        if (birthdayBuilder_ == null) {
          birthdayBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                  getBirthday(),
                  getParentForChildren(),
                  isClean());
          birthday_ = null;
        }
        return birthdayBuilder_;
      }

      private java.lang.Object email_ = "";
      /**
       * <code>string email = 5;</code>
       */
      public java.lang.String getEmail() {
        java.lang.Object ref = email_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          email_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>string email = 5;</code>
       */
      public com.google.protobuf.ByteString
          getEmailBytes() {
        java.lang.Object ref = email_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          email_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string email = 5;</code>
       */
      public Builder setEmail(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        email_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>string email = 5;</code>
       */
      public Builder clearEmail() {
        
        email_ = getDefaultInstance().getEmail();
        onChanged();
        return this;
      }
      /**
       * <code>string email = 5;</code>
       */
      public Builder setEmailBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        email_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object mobile_ = "";
      /**
       * <code>string mobile = 6;</code>
       */
      public java.lang.String getMobile() {
        java.lang.Object ref = mobile_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          mobile_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>string mobile = 6;</code>
       */
      public com.google.protobuf.ByteString
          getMobileBytes() {
        java.lang.Object ref = mobile_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          mobile_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string mobile = 6;</code>
       */
      public Builder setMobile(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        mobile_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>string mobile = 6;</code>
       */
      public Builder clearMobile() {
        
        mobile_ = getDefaultInstance().getMobile();
        onChanged();
        return this;
      }
      /**
       * <code>string mobile = 6;</code>
       */
      public Builder setMobileBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        mobile_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object address_ = "";
      /**
       * <code>string address = 7;</code>
       */
      public java.lang.String getAddress() {
        java.lang.Object ref = address_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          address_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>string address = 7;</code>
       */
      public com.google.protobuf.ByteString
          getAddressBytes() {
        java.lang.Object ref = address_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          address_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string address = 7;</code>
       */
      public Builder setAddress(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        address_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>string address = 7;</code>
       */
      public Builder clearAddress() {
        
        address_ = getDefaultInstance().getAddress();
        onChanged();
        return this;
      }
      /**
       * <code>string address = 7;</code>
       */
      public Builder setAddressBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        address_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object icon_ = "";
      /**
       * <code>string icon = 8;</code>
       */
      public java.lang.String getIcon() {
        java.lang.Object ref = icon_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          icon_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>string icon = 8;</code>
       */
      public com.google.protobuf.ByteString
          getIconBytes() {
        java.lang.Object ref = icon_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          icon_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string icon = 8;</code>
       */
      public Builder setIcon(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        icon_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>string icon = 8;</code>
       */
      public Builder clearIcon() {
        
        icon_ = getDefaultInstance().getIcon();
        onChanged();
        return this;
      }
      /**
       * <code>string icon = 8;</code>
       */
      public Builder setIconBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        icon_ = value;
        onChanged();
        return this;
      }

      private com.google.protobuf.Internal.IntList permissions_ = emptyIntList();
      private void ensurePermissionsIsMutable() {
        if (!((bitField0_ & 0x00000100) != 0)) {
          permissions_ = mutableCopy(permissions_);
          bitField0_ |= 0x00000100;
         }
      }
      /**
       * <code>repeated int32 permissions = 9;</code>
       */
      public java.util.List<java.lang.Integer>
          getPermissionsList() {
        return ((bitField0_ & 0x00000100) != 0) ?
                 java.util.Collections.unmodifiableList(permissions_) : permissions_;
      }
      /**
       * <code>repeated int32 permissions = 9;</code>
       */
      public int getPermissionsCount() {
        return permissions_.size();
      }
      /**
       * <code>repeated int32 permissions = 9;</code>
       */
      public int getPermissions(int index) {
        return permissions_.getInt(index);
      }
      /**
       * <code>repeated int32 permissions = 9;</code>
       */
      public Builder setPermissions(
          int index, int value) {
        ensurePermissionsIsMutable();
        permissions_.setInt(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 permissions = 9;</code>
       */
      public Builder addPermissions(int value) {
        ensurePermissionsIsMutable();
        permissions_.addInt(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 permissions = 9;</code>
       */
      public Builder addAllPermissions(
          java.lang.Iterable<? extends java.lang.Integer> values) {
        ensurePermissionsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, permissions_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 permissions = 9;</code>
       */
      public Builder clearPermissions() {
        permissions_ = emptyIntList();
        bitField0_ = (bitField0_ & ~0x00000100);
        onChanged();
        return this;
      }

      private int status_ ;
      /**
       * <code>int32 status = 10;</code>
       */
      public int getStatus() {
        return status_;
      }
      /**
       * <code>int32 status = 10;</code>
       */
      public Builder setStatus(int value) {
        
        status_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>int32 status = 10;</code>
       */
      public Builder clearStatus() {
        
        status_ = 0;
        onChanged();
        return this;
      }

      private com.google.protobuf.Timestamp createTime_;
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createTimeBuilder_;
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public boolean hasCreateTime() {
        return createTimeBuilder_ != null || createTime_ != null;
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public com.google.protobuf.Timestamp getCreateTime() {
        if (createTimeBuilder_ == null) {
          return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_;
        } else {
          return createTimeBuilder_.getMessage();
        }
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public Builder setCreateTime(com.google.protobuf.Timestamp value) {
        if (createTimeBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          createTime_ = value;
          onChanged();
        } else {
          createTimeBuilder_.setMessage(value);
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public Builder setCreateTime(
          com.google.protobuf.Timestamp.Builder builderForValue) {
        if (createTimeBuilder_ == null) {
          createTime_ = builderForValue.build();
          onChanged();
        } else {
          createTimeBuilder_.setMessage(builderForValue.build());
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public Builder mergeCreateTime(com.google.protobuf.Timestamp value) {
        if (createTimeBuilder_ == null) {
          if (createTime_ != null) {
            createTime_ =
              com.google.protobuf.Timestamp.newBuilder(createTime_).mergeFrom(value).buildPartial();
          } else {
            createTime_ = value;
          }
          onChanged();
        } else {
          createTimeBuilder_.mergeFrom(value);
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public Builder clearCreateTime() {
        if (createTimeBuilder_ == null) {
          createTime_ = null;
          onChanged();
        } else {
          createTime_ = null;
          createTimeBuilder_ = null;
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public com.google.protobuf.Timestamp.Builder getCreateTimeBuilder() {
        
        onChanged();
        return getCreateTimeFieldBuilder().getBuilder();
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() {
        if (createTimeBuilder_ != null) {
          return createTimeBuilder_.getMessageOrBuilder();
        } else {
          return createTime_ == null ?
              com.google.protobuf.Timestamp.getDefaultInstance() : createTime_;
        }
      }
      /**
       * <code>.google.protobuf.Timestamp createTime = 11;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
          getCreateTimeFieldBuilder() {
        if (createTimeBuilder_ == null) {
          createTimeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                  getCreateTime(),
                  getParentForChildren(),
                  isClean());
          createTime_ = null;
        }
        return createTimeBuilder_;
      }

      private com.google.protobuf.Timestamp updateTime_;
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> updateTimeBuilder_;
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public boolean hasUpdateTime() {
        return updateTimeBuilder_ != null || updateTime_ != null;
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public com.google.protobuf.Timestamp getUpdateTime() {
        if (updateTimeBuilder_ == null) {
          return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_;
        } else {
          return updateTimeBuilder_.getMessage();
        }
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public Builder setUpdateTime(com.google.protobuf.Timestamp value) {
        if (updateTimeBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          updateTime_ = value;
          onChanged();
        } else {
          updateTimeBuilder_.setMessage(value);
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public Builder setUpdateTime(
          com.google.protobuf.Timestamp.Builder builderForValue) {
        if (updateTimeBuilder_ == null) {
          updateTime_ = builderForValue.build();
          onChanged();
        } else {
          updateTimeBuilder_.setMessage(builderForValue.build());
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) {
        if (updateTimeBuilder_ == null) {
          if (updateTime_ != null) {
            updateTime_ =
              com.google.protobuf.Timestamp.newBuilder(updateTime_).mergeFrom(value).buildPartial();
          } else {
            updateTime_ = value;
          }
          onChanged();
        } else {
          updateTimeBuilder_.mergeFrom(value);
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public Builder clearUpdateTime() {
        if (updateTimeBuilder_ == null) {
          updateTime_ = null;
          onChanged();
        } else {
          updateTime_ = null;
          updateTimeBuilder_ = null;
        }

        return this;
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() {
        
        onChanged();
        return getUpdateTimeFieldBuilder().getBuilder();
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() {
        if (updateTimeBuilder_ != null) {
          return updateTimeBuilder_.getMessageOrBuilder();
        } else {
          return updateTime_ == null ?
              com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_;
        }
      }
      /**
       * <code>.google.protobuf.Timestamp updateTime = 12;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
          getUpdateTimeFieldBuilder() {
        if (updateTimeBuilder_ == null) {
          updateTimeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                  getUpdateTime(),
                  getParentForChildren(),
                  isClean());
          updateTime_ = null;
        }
        return updateTimeBuilder_;
      }
      @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.benchmark.bean.User)
    }

    // @@protoc_insertion_point(class_scope:org.apache.dubbo.benchmark.bean.User)
    private static final org.apache.dubbo.benchmark.bean.PagePB.User DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.dubbo.benchmark.bean.PagePB.User();
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.User getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

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

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

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

    @java.lang.Override
    public org.apache.dubbo.benchmark.bean.PagePB.User getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface RequestOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.apache.dubbo.benchmark.bean.Request)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>int64 id = 1;</code>
     */
    long getId();

    /**
     * <code>int32 page = 2;</code>
     */
    int getPage();

    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
     */
    boolean hasUser();
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.User getUser();
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUserOrBuilder();

    /**
     * <code>string email = 4;</code>
     */
    java.lang.String getEmail();
    /**
     * <code>string email = 4;</code>
     */
    com.google.protobuf.ByteString
        getEmailBytes();
  }
  /**
   * Protobuf type {@code org.apache.dubbo.benchmark.bean.Request}
   */
  public  static final class Request extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:org.apache.dubbo.benchmark.bean.Request)
      RequestOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Request.newBuilder() to construct.
    private Request(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Request() {
      email_ = "";
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private Request(
        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 8: {

              id_ = input.readInt64();
              break;
            }
            case 16: {

              page_ = input.readInt32();
              break;
            }
            case 26: {
              org.apache.dubbo.benchmark.bean.PagePB.User.Builder subBuilder = null;
              if (user_ != null) {
                subBuilder = user_.toBuilder();
              }
              user_ = input.readMessage(org.apache.dubbo.benchmark.bean.PagePB.User.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(user_);
                user_ = subBuilder.buildPartial();
              }

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

              email_ = s;
              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.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Request_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Request_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.dubbo.benchmark.bean.PagePB.Request.class, org.apache.dubbo.benchmark.bean.PagePB.Request.Builder.class);
    }

    public static final int ID_FIELD_NUMBER = 1;
    private long id_;
    /**
     * <code>int64 id = 1;</code>
     */
    public long getId() {
      return id_;
    }

    public static final int PAGE_FIELD_NUMBER = 2;
    private int page_;
    /**
     * <code>int32 page = 2;</code>
     */
    public int getPage() {
      return page_;
    }

    public static final int USER_FIELD_NUMBER = 3;
    private org.apache.dubbo.benchmark.bean.PagePB.User user_;
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
     */
    public boolean hasUser() {
      return user_ != null;
    }
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.User getUser() {
      return user_ == null ? org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance() : user_;
    }
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUserOrBuilder() {
      return getUser();
    }

    public static final int EMAIL_FIELD_NUMBER = 4;
    private volatile java.lang.Object email_;
    /**
     * <code>string email = 4;</code>
     */
    public java.lang.String getEmail() {
      java.lang.Object ref = email_;
      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();
        email_ = s;
        return s;
      }
    }
    /**
     * <code>string email = 4;</code>
     */
    public com.google.protobuf.ByteString
        getEmailBytes() {
      java.lang.Object ref = email_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        email_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    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 (id_ != 0L) {
        output.writeInt64(1, id_);
      }
      if (page_ != 0) {
        output.writeInt32(2, page_);
      }
      if (user_ != null) {
        output.writeMessage(3, getUser());
      }
      if (!getEmailBytes().isEmpty()) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, email_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (id_ != 0L) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, id_);
      }
      if (page_ != 0) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, page_);
      }
      if (user_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getUser());
      }
      if (!getEmailBytes().isEmpty()) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, email_);
      }
      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.benchmark.bean.PagePB.Request)) {
        return super.equals(obj);
      }
      org.apache.dubbo.benchmark.bean.PagePB.Request other = (org.apache.dubbo.benchmark.bean.PagePB.Request) obj;

      if (getId()
          != other.getId()) return false;
      if (getPage()
          != other.getPage()) return false;
      if (hasUser() != other.hasUser()) return false;
      if (hasUser()) {
        if (!getUser()
            .equals(other.getUser())) return false;
      }
      if (!getEmail()
          .equals(other.getEmail())) 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) + ID_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
          getId());
      hash = (37 * hash) + PAGE_FIELD_NUMBER;
      hash = (53 * hash) + getPage();
      if (hasUser()) {
        hash = (37 * hash) + USER_FIELD_NUMBER;
        hash = (53 * hash) + getUser().hashCode();
      }
      hash = (37 * hash) + EMAIL_FIELD_NUMBER;
      hash = (53 * hash) + getEmail().hashCode();
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.Request parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Request 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.benchmark.bean.PagePB.Request parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Request 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.benchmark.bean.PagePB.Request parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Request parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Request parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Request 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.benchmark.bean.PagePB.Request parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Request 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.benchmark.bean.PagePB.Request parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Request 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.benchmark.bean.PagePB.Request 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;
    }
    /**
     * Protobuf type {@code org.apache.dubbo.benchmark.bean.Request}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.apache.dubbo.benchmark.bean.Request)
        org.apache.dubbo.benchmark.bean.PagePB.RequestOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Request_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Request_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.dubbo.benchmark.bean.PagePB.Request.class, org.apache.dubbo.benchmark.bean.PagePB.Request.Builder.class);
      }

      // Construct using org.apache.dubbo.benchmark.bean.PagePB.Request.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();
        id_ = 0L;

        page_ = 0;

        if (userBuilder_ == null) {
          user_ = null;
        } else {
          user_ = null;
          userBuilder_ = null;
        }
        email_ = "";

        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Request_descriptor;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Request getDefaultInstanceForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.Request.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Request build() {
        org.apache.dubbo.benchmark.bean.PagePB.Request result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Request buildPartial() {
        org.apache.dubbo.benchmark.bean.PagePB.Request result = new org.apache.dubbo.benchmark.bean.PagePB.Request(this);
        result.id_ = id_;
        result.page_ = page_;
        if (userBuilder_ == null) {
          result.user_ = user_;
        } else {
          result.user_ = userBuilder_.build();
        }
        result.email_ = email_;
        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.benchmark.bean.PagePB.Request) {
          return mergeFrom((org.apache.dubbo.benchmark.bean.PagePB.Request)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.dubbo.benchmark.bean.PagePB.Request other) {
        if (other == org.apache.dubbo.benchmark.bean.PagePB.Request.getDefaultInstance()) return this;
        if (other.getId() != 0L) {
          setId(other.getId());
        }
        if (other.getPage() != 0) {
          setPage(other.getPage());
        }
        if (other.hasUser()) {
          mergeUser(other.getUser());
        }
        if (!other.getEmail().isEmpty()) {
          email_ = other.email_;
          onChanged();
        }
        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.benchmark.bean.PagePB.Request parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.dubbo.benchmark.bean.PagePB.Request) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      private long id_ ;
      /**
       * <code>int64 id = 1;</code>
       */
      public long getId() {
        return id_;
      }
      /**
       * <code>int64 id = 1;</code>
       */
      public Builder setId(long value) {
        
        id_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>int64 id = 1;</code>
       */
      public Builder clearId() {
        
        id_ = 0L;
        onChanged();
        return this;
      }

      private int page_ ;
      /**
       * <code>int32 page = 2;</code>
       */
      public int getPage() {
        return page_;
      }
      /**
       * <code>int32 page = 2;</code>
       */
      public Builder setPage(int value) {
        
        page_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>int32 page = 2;</code>
       */
      public Builder clearPage() {
        
        page_ = 0;
        onChanged();
        return this;
      }

      private org.apache.dubbo.benchmark.bean.PagePB.User user_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> userBuilder_;
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public boolean hasUser() {
        return userBuilder_ != null || user_ != null;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User getUser() {
        if (userBuilder_ == null) {
          return user_ == null ? org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance() : user_;
        } else {
          return userBuilder_.getMessage();
        }
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public Builder setUser(org.apache.dubbo.benchmark.bean.PagePB.User value) {
        if (userBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          user_ = value;
          onChanged();
        } else {
          userBuilder_.setMessage(value);
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public Builder setUser(
          org.apache.dubbo.benchmark.bean.PagePB.User.Builder builderForValue) {
        if (userBuilder_ == null) {
          user_ = builderForValue.build();
          onChanged();
        } else {
          userBuilder_.setMessage(builderForValue.build());
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public Builder mergeUser(org.apache.dubbo.benchmark.bean.PagePB.User value) {
        if (userBuilder_ == null) {
          if (user_ != null) {
            user_ =
              org.apache.dubbo.benchmark.bean.PagePB.User.newBuilder(user_).mergeFrom(value).buildPartial();
          } else {
            user_ = value;
          }
          onChanged();
        } else {
          userBuilder_.mergeFrom(value);
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public Builder clearUser() {
        if (userBuilder_ == null) {
          user_ = null;
          onChanged();
        } else {
          user_ = null;
          userBuilder_ = null;
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User.Builder getUserBuilder() {
        
        onChanged();
        return getUserFieldBuilder().getBuilder();
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUserOrBuilder() {
        if (userBuilder_ != null) {
          return userBuilder_.getMessageOrBuilder();
        } else {
          return user_ == null ?
              org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance() : user_;
        }
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> 
          getUserFieldBuilder() {
        if (userBuilder_ == null) {
          userBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder>(
                  getUser(),
                  getParentForChildren(),
                  isClean());
          user_ = null;
        }
        return userBuilder_;
      }

      private java.lang.Object email_ = "";
      /**
       * <code>string email = 4;</code>
       */
      public java.lang.String getEmail() {
        java.lang.Object ref = email_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          email_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>string email = 4;</code>
       */
      public com.google.protobuf.ByteString
          getEmailBytes() {
        java.lang.Object ref = email_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          email_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>string email = 4;</code>
       */
      public Builder setEmail(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  
        email_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>string email = 4;</code>
       */
      public Builder clearEmail() {
        
        email_ = getDefaultInstance().getEmail();
        onChanged();
        return this;
      }
      /**
       * <code>string email = 4;</code>
       */
      public Builder setEmailBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
        
        email_ = value;
        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.benchmark.bean.Request)
    }

    // @@protoc_insertion_point(class_scope:org.apache.dubbo.benchmark.bean.Request)
    private static final org.apache.dubbo.benchmark.bean.PagePB.Request DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.dubbo.benchmark.bean.PagePB.Request();
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.Request getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

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

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

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

    @java.lang.Override
    public org.apache.dubbo.benchmark.bean.PagePB.Request getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ResponseOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.apache.dubbo.benchmark.bean.Response)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>bool state = 1;</code>
     */
    boolean getState();

    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
     */
    boolean hasUser();
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.User getUser();
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUserOrBuilder();

    /**
     * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
     */
    boolean hasPage();
    /**
     * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.Page getPage();
    /**
     * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
     */
    org.apache.dubbo.benchmark.bean.PagePB.PageOrBuilder getPageOrBuilder();
  }
  /**
   * Protobuf type {@code org.apache.dubbo.benchmark.bean.Response}
   */
  public  static final class Response extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:org.apache.dubbo.benchmark.bean.Response)
      ResponseOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Response.newBuilder() to construct.
    private Response(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Response() {
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private Response(
        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 8: {

              state_ = input.readBool();
              break;
            }
            case 18: {
              org.apache.dubbo.benchmark.bean.PagePB.User.Builder subBuilder = null;
              if (user_ != null) {
                subBuilder = user_.toBuilder();
              }
              user_ = input.readMessage(org.apache.dubbo.benchmark.bean.PagePB.User.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(user_);
                user_ = subBuilder.buildPartial();
              }

              break;
            }
            case 26: {
              org.apache.dubbo.benchmark.bean.PagePB.Page.Builder subBuilder = null;
              if (page_ != null) {
                subBuilder = page_.toBuilder();
              }
              page_ = input.readMessage(org.apache.dubbo.benchmark.bean.PagePB.Page.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(page_);
                page_ = 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 {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Response_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Response_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.dubbo.benchmark.bean.PagePB.Response.class, org.apache.dubbo.benchmark.bean.PagePB.Response.Builder.class);
    }

    public static final int STATE_FIELD_NUMBER = 1;
    private boolean state_;
    /**
     * <code>bool state = 1;</code>
     */
    public boolean getState() {
      return state_;
    }

    public static final int USER_FIELD_NUMBER = 2;
    private org.apache.dubbo.benchmark.bean.PagePB.User user_;
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
     */
    public boolean hasUser() {
      return user_ != null;
    }
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.User getUser() {
      return user_ == null ? org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance() : user_;
    }
    /**
     * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUserOrBuilder() {
      return getUser();
    }

    public static final int PAGE_FIELD_NUMBER = 3;
    private org.apache.dubbo.benchmark.bean.PagePB.Page page_;
    /**
     * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
     */
    public boolean hasPage() {
      return page_ != null;
    }
    /**
     * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.Page getPage() {
      return page_ == null ? org.apache.dubbo.benchmark.bean.PagePB.Page.getDefaultInstance() : page_;
    }
    /**
     * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
     */
    public org.apache.dubbo.benchmark.bean.PagePB.PageOrBuilder getPageOrBuilder() {
      return getPage();
    }

    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 (state_ != false) {
        output.writeBool(1, state_);
      }
      if (user_ != null) {
        output.writeMessage(2, getUser());
      }
      if (page_ != null) {
        output.writeMessage(3, getPage());
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (state_ != false) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(1, state_);
      }
      if (user_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getUser());
      }
      if (page_ != null) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getPage());
      }
      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.benchmark.bean.PagePB.Response)) {
        return super.equals(obj);
      }
      org.apache.dubbo.benchmark.bean.PagePB.Response other = (org.apache.dubbo.benchmark.bean.PagePB.Response) obj;

      if (getState()
          != other.getState()) return false;
      if (hasUser() != other.hasUser()) return false;
      if (hasUser()) {
        if (!getUser()
            .equals(other.getUser())) return false;
      }
      if (hasPage() != other.hasPage()) return false;
      if (hasPage()) {
        if (!getPage()
            .equals(other.getPage())) 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) + STATE_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
          getState());
      if (hasUser()) {
        hash = (37 * hash) + USER_FIELD_NUMBER;
        hash = (53 * hash) + getUser().hashCode();
      }
      if (hasPage()) {
        hash = (37 * hash) + PAGE_FIELD_NUMBER;
        hash = (53 * hash) + getPage().hashCode();
      }
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.Response parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Response 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.benchmark.bean.PagePB.Response parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Response 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.benchmark.bean.PagePB.Response parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Response parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Response parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Response 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.benchmark.bean.PagePB.Response parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Response 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.benchmark.bean.PagePB.Response parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.dubbo.benchmark.bean.PagePB.Response 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.benchmark.bean.PagePB.Response 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;
    }
    /**
     * Protobuf type {@code org.apache.dubbo.benchmark.bean.Response}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.apache.dubbo.benchmark.bean.Response)
        org.apache.dubbo.benchmark.bean.PagePB.ResponseOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Response_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Response_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.dubbo.benchmark.bean.PagePB.Response.class, org.apache.dubbo.benchmark.bean.PagePB.Response.Builder.class);
      }

      // Construct using org.apache.dubbo.benchmark.bean.PagePB.Response.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();
        state_ = false;

        if (userBuilder_ == null) {
          user_ = null;
        } else {
          user_ = null;
          userBuilder_ = null;
        }
        if (pageBuilder_ == null) {
          page_ = null;
        } else {
          page_ = null;
          pageBuilder_ = null;
        }
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.internal_static_org_apache_dubbo_benchmark_bean_Response_descriptor;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Response getDefaultInstanceForType() {
        return org.apache.dubbo.benchmark.bean.PagePB.Response.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Response build() {
        org.apache.dubbo.benchmark.bean.PagePB.Response result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.dubbo.benchmark.bean.PagePB.Response buildPartial() {
        org.apache.dubbo.benchmark.bean.PagePB.Response result = new org.apache.dubbo.benchmark.bean.PagePB.Response(this);
        result.state_ = state_;
        if (userBuilder_ == null) {
          result.user_ = user_;
        } else {
          result.user_ = userBuilder_.build();
        }
        if (pageBuilder_ == null) {
          result.page_ = page_;
        } else {
          result.page_ = pageBuilder_.build();
        }
        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.benchmark.bean.PagePB.Response) {
          return mergeFrom((org.apache.dubbo.benchmark.bean.PagePB.Response)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.dubbo.benchmark.bean.PagePB.Response other) {
        if (other == org.apache.dubbo.benchmark.bean.PagePB.Response.getDefaultInstance()) return this;
        if (other.getState() != false) {
          setState(other.getState());
        }
        if (other.hasUser()) {
          mergeUser(other.getUser());
        }
        if (other.hasPage()) {
          mergePage(other.getPage());
        }
        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.benchmark.bean.PagePB.Response parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.dubbo.benchmark.bean.PagePB.Response) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      private boolean state_ ;
      /**
       * <code>bool state = 1;</code>
       */
      public boolean getState() {
        return state_;
      }
      /**
       * <code>bool state = 1;</code>
       */
      public Builder setState(boolean value) {
        
        state_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>bool state = 1;</code>
       */
      public Builder clearState() {
        
        state_ = false;
        onChanged();
        return this;
      }

      private org.apache.dubbo.benchmark.bean.PagePB.User user_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> userBuilder_;
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public boolean hasUser() {
        return userBuilder_ != null || user_ != null;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User getUser() {
        if (userBuilder_ == null) {
          return user_ == null ? org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance() : user_;
        } else {
          return userBuilder_.getMessage();
        }
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public Builder setUser(org.apache.dubbo.benchmark.bean.PagePB.User value) {
        if (userBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          user_ = value;
          onChanged();
        } else {
          userBuilder_.setMessage(value);
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public Builder setUser(
          org.apache.dubbo.benchmark.bean.PagePB.User.Builder builderForValue) {
        if (userBuilder_ == null) {
          user_ = builderForValue.build();
          onChanged();
        } else {
          userBuilder_.setMessage(builderForValue.build());
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public Builder mergeUser(org.apache.dubbo.benchmark.bean.PagePB.User value) {
        if (userBuilder_ == null) {
          if (user_ != null) {
            user_ =
              org.apache.dubbo.benchmark.bean.PagePB.User.newBuilder(user_).mergeFrom(value).buildPartial();
          } else {
            user_ = value;
          }
          onChanged();
        } else {
          userBuilder_.mergeFrom(value);
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public Builder clearUser() {
        if (userBuilder_ == null) {
          user_ = null;
          onChanged();
        } else {
          user_ = null;
          userBuilder_ = null;
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.User.Builder getUserBuilder() {
        
        onChanged();
        return getUserFieldBuilder().getBuilder();
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder getUserOrBuilder() {
        if (userBuilder_ != null) {
          return userBuilder_.getMessageOrBuilder();
        } else {
          return user_ == null ?
              org.apache.dubbo.benchmark.bean.PagePB.User.getDefaultInstance() : user_;
        }
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.User user = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder> 
          getUserFieldBuilder() {
        if (userBuilder_ == null) {
          userBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.dubbo.benchmark.bean.PagePB.User, org.apache.dubbo.benchmark.bean.PagePB.User.Builder, org.apache.dubbo.benchmark.bean.PagePB.UserOrBuilder>(
                  getUser(),
                  getParentForChildren(),
                  isClean());
          user_ = null;
        }
        return userBuilder_;
      }

      private org.apache.dubbo.benchmark.bean.PagePB.Page page_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.Page, org.apache.dubbo.benchmark.bean.PagePB.Page.Builder, org.apache.dubbo.benchmark.bean.PagePB.PageOrBuilder> pageBuilder_;
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public boolean hasPage() {
        return pageBuilder_ != null || page_ != null;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.Page getPage() {
        if (pageBuilder_ == null) {
          return page_ == null ? org.apache.dubbo.benchmark.bean.PagePB.Page.getDefaultInstance() : page_;
        } else {
          return pageBuilder_.getMessage();
        }
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public Builder setPage(org.apache.dubbo.benchmark.bean.PagePB.Page value) {
        if (pageBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          page_ = value;
          onChanged();
        } else {
          pageBuilder_.setMessage(value);
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public Builder setPage(
          org.apache.dubbo.benchmark.bean.PagePB.Page.Builder builderForValue) {
        if (pageBuilder_ == null) {
          page_ = builderForValue.build();
          onChanged();
        } else {
          pageBuilder_.setMessage(builderForValue.build());
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public Builder mergePage(org.apache.dubbo.benchmark.bean.PagePB.Page value) {
        if (pageBuilder_ == null) {
          if (page_ != null) {
            page_ =
              org.apache.dubbo.benchmark.bean.PagePB.Page.newBuilder(page_).mergeFrom(value).buildPartial();
          } else {
            page_ = value;
          }
          onChanged();
        } else {
          pageBuilder_.mergeFrom(value);
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public Builder clearPage() {
        if (pageBuilder_ == null) {
          page_ = null;
          onChanged();
        } else {
          page_ = null;
          pageBuilder_ = null;
        }

        return this;
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.Page.Builder getPageBuilder() {
        
        onChanged();
        return getPageFieldBuilder().getBuilder();
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      public org.apache.dubbo.benchmark.bean.PagePB.PageOrBuilder getPageOrBuilder() {
        if (pageBuilder_ != null) {
          return pageBuilder_.getMessageOrBuilder();
        } else {
          return page_ == null ?
              org.apache.dubbo.benchmark.bean.PagePB.Page.getDefaultInstance() : page_;
        }
      }
      /**
       * <code>.org.apache.dubbo.benchmark.bean.Page page = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.dubbo.benchmark.bean.PagePB.Page, org.apache.dubbo.benchmark.bean.PagePB.Page.Builder, org.apache.dubbo.benchmark.bean.PagePB.PageOrBuilder> 
          getPageFieldBuilder() {
        if (pageBuilder_ == null) {
          pageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.dubbo.benchmark.bean.PagePB.Page, org.apache.dubbo.benchmark.bean.PagePB.Page.Builder, org.apache.dubbo.benchmark.bean.PagePB.PageOrBuilder>(
                  getPage(),
                  getParentForChildren(),
                  isClean());
          page_ = null;
        }
        return pageBuilder_;
      }
      @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.benchmark.bean.Response)
    }

    // @@protoc_insertion_point(class_scope:org.apache.dubbo.benchmark.bean.Response)
    private static final org.apache.dubbo.benchmark.bean.PagePB.Response DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.dubbo.benchmark.bean.PagePB.Response();
    }

    public static org.apache.dubbo.benchmark.bean.PagePB.Response getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

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

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

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

    @java.lang.Override
    public org.apache.dubbo.benchmark.bean.PagePB.Response getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_benchmark_bean_Page_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_benchmark_bean_Page_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_benchmark_bean_User_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_benchmark_bean_User_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_benchmark_bean_Request_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_benchmark_bean_Request_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_org_apache_dubbo_benchmark_bean_Response_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_org_apache_dubbo_benchmark_bean_Response_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\nPage.proto\022\037org.apache.dubbo.benchmark" +
      ".bean\032\037google/protobuf/timestamp.proto\"[" +
      "\n\004Page\0224\n\005users\030\001 \003(\0132%.org.apache.dubbo" +
      ".benchmark.bean.User\022\016\n\006pageNo\030\002 \001(\005\022\r\n\005" +
      "total\030\003 \001(\005\"\236\002\n\004User\022\n\n\002id\030\001 \001(\003\022\014\n\004name" +
      "\030\002 \001(\t\022\013\n\003sex\030\003 \001(\005\022,\n\010birthday\030\004 \001(\0132\032." +
      "google.protobuf.Timestamp\022\r\n\005email\030\005 \001(\t" +
      "\022\016\n\006mobile\030\006 \001(\t\022\017\n\007address\030\007 \001(\t\022\014\n\004ico" +
      "n\030\010 \001(\t\022\023\n\013permissions\030\t \003(\005\022\016\n\006status\030\n" +
      " \001(\005\022.\n\ncreateTime\030\013 \001(\0132\032.google.protob" +
      "uf.Timestamp\022.\n\nupdateTime\030\014 \001(\0132\032.googl" +
      "e.protobuf.Timestamp\"g\n\007Request\022\n\n\002id\030\001 " +
      "\001(\003\022\014\n\004page\030\002 \001(\005\0223\n\004user\030\003 \001(\0132%.org.ap" +
      "ache.dubbo.benchmark.bean.User\022\r\n\005email\030" +
      "\004 \001(\t\"\203\001\n\010Response\022\r\n\005state\030\001 \001(\010\0223\n\004use" +
      "r\030\002 \001(\0132%.org.apache.dubbo.benchmark.bea" +
      "n.User\0223\n\004page\030\003 \001(\0132%.org.apache.dubbo." +
      "benchmark.bean.Page2\223\003\n\013UserService\022`\n\te" +
      "xistUser\022(.org.apache.dubbo.benchmark.be" +
      "an.Request\032).org.apache.dubbo.benchmark." +
      "bean.Response\022a\n\ncreateUser\022(.org.apache" +
      ".dubbo.benchmark.bean.Request\032).org.apac" +
      "he.dubbo.benchmark.bean.Response\022^\n\007getU" +
      "ser\022(.org.apache.dubbo.benchmark.bean.Re" +
      "quest\032).org.apache.dubbo.benchmark.bean." +
      "Response\022_\n\010listUser\022(.org.apache.dubbo." +
      "benchmark.bean.Request\032).org.apache.dubb" +
      "o.benchmark.bean.ResponseB)\n\037org.apache." +
      "dubbo.benchmark.beanB\006PagePBP\000b\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[] {
          com.google.protobuf.TimestampProto.getDescriptor(),
        }, assigner);
    internal_static_org_apache_dubbo_benchmark_bean_Page_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_org_apache_dubbo_benchmark_bean_Page_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_benchmark_bean_Page_descriptor,
        new java.lang.String[] { "Users", "PageNo", "Total", });
    internal_static_org_apache_dubbo_benchmark_bean_User_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_org_apache_dubbo_benchmark_bean_User_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_benchmark_bean_User_descriptor,
        new java.lang.String[] { "Id", "Name", "Sex", "Birthday", "Email", "Mobile", "Address", "Icon", "Permissions", "Status", "CreateTime", "UpdateTime", });
    internal_static_org_apache_dubbo_benchmark_bean_Request_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_org_apache_dubbo_benchmark_bean_Request_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_benchmark_bean_Request_descriptor,
        new java.lang.String[] { "Id", "Page", "User", "Email", });
    internal_static_org_apache_dubbo_benchmark_bean_Response_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_org_apache_dubbo_benchmark_bean_Response_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_org_apache_dubbo_benchmark_bean_Response_descriptor,
        new java.lang.String[] { "State", "User", "Page", });
    com.google.protobuf.TimestampProto.getDescriptor();
  }

  // @@protoc_insertion_point(outer_class_scope)
}
